Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Rich H.J for C programmers.2006.pdf
Скачиваний:
19
Добавлен:
23.08.2013
Размер:
1.79 Mб
Скачать

1. Introduction

This book will tell you enough about J for you to use it as a language for developing serious applications, but it is about more than learning the J language: it is also about 'thinking big' in programming, and how programming in J is fundamentally different from programming in C. C programs deal intimately with scalars (single numbers and characters), and even when they combine those scalars into arrays and structures, the operations on the arrays and structures are defined by operations on the scalars. To ensure that each item of an array is operated on, loops are created that visit each element of the array and perform a scalar operation on the element.

Writing code in a scalar language makes you rather like a general who gives orders to his troops by visiting each one and whispering in his ear. That touch-of-Harry kind of generalling can achieve victorious results, and it has the advantage that the orders can be tailored to the man, but its disadvantages are significant: the general spends much mental energy in formulating individual orders and much breath in communicating them individually; more significant, his limited attention is drawn toward individuals and away from the army as a whole. Even the great Rommel was overtaxed at times.

The J programmer is, in contrast, a general who stands before his army and snaps out orders to the army as a whole. Every man receives the same order, but the order itself contains enough detail for the individual men to act appropriately. Such a general can command a corps as easily as a platoon, and always has the 'big picture' in mind.

OK, maybe you're not Rommel, but you are a working programmer, and you suspect that very few practical programs can be represented as array operations—matrix multiplication maybe, or adding a list of numbers—and that, even if a wide range of programs were possible, the set of operations supported must be too vast to be practical: wouldn't we need an array operation for every possible program?

The first half of this book is devoted to showing you that it is indeed possible to write meaningful programs with array operations. We take the approach of looking at the different ways loops are used, and seeing what facilities J has for producing the same result using array operations. We will find that J contains a couple of dozen arrayprocessing primitives and a dozen or so very cleverly chosen pipe-fittings that allow those primitives to be connected together to provide the limitless supply of arrayprocessing functions needed for practical programming.

Interspersed with the elaboration of more and more intricate array operations are treatments of other matters of use in practical programming: structure definition, input and output, performance measurement, calling DLLs, modular programming. Eventually we will see how to use if-then-else and do-while in J, though you will have learned more elegant ways to get the same results.

The last portion of the book is devoted to the optional topic of tacit programming, J's language for functional programming. Tacit programming is an extremely terse way of expressing algorithms, one that allows programs that have been compressed from a page of C into a few lines of J to be compressed still further.

1

2. Culture Shock

A C Programmer's First Thoughts On J

This doesn't look like a program. Where did the program go?

You have gotten used to the pace and structure of C. You can recognize a loop, you figure out what the loop is doing, you see what variables it sets. The assignments and the loops are signposts that direct your analysis of code.

In J, every operator has a loop built in, so they don't jump out at you in the same way. And because the syntax of J is so terse, and arrays use the same syntax as single variables, there is much less need for temporary variables.

Here's an example. Figure out what the following code does:

int i, j, maxcol = 0; float maxval = x[0][0]; for(i = 0;i<=xsize0;++i) {

for(j = 0;j<=xsize1;++j) { if(x[i][j] > maxval) {

maxval = x[i][j]; maxcol = j;

}

}

}

Not too hard. When the code finishes, maxval is the largest element in the array x, and maxcol is the column number it was in. As it happens, all I wanted was the column number, but there was no way for you to know that.

The same code in J:

maxcol =. (i. >./) >./ x

With some practice, you will learn to read this code just as easily as you read the C. You will recognize the / as an indicator of a loop, and the i. as an indicator for a search.

What happened to the if statement?

It's built into the >. primitive. Just as most loops are hidden inside primitives, so are most conditionals. The functions you write can also contain built-in conditionals.

What's the statement delimiter?

There isn't one. Statements are exactly one line long.

2

I've looked at some J code. Every other character is a period or a colon. I've got spots before my eyes. How can anybody read this stuff?

You'll get used to it. J has a great many primitives, and it's important to keep the names short so that you can fit a lot of computation on one line; so the names are either single characters, like >, or a character with a period or space appended (>. and >:). The period/colon is just part of the name. Single letters with period/colon, like i., are also used for primitives. If you want to assign your own names to the primitives, you are allowed to, but pretty soon you'll want to go back to the shorter names to save space and typing.

Where are the declarations? Doesn't J use arrays? How do I know what the type of a variable is?

Oh yeah, J uses arrays. Any variable can be an array. As for what the type and dimensioning is: you assigned the variable, didn't you? It contains whatever you put into it, a number, a string, an array, a structure... J will remember. If your program logic requires you to find out the current attributes of a variable, J can tell you.

Every J program, both primitives and programs that you write, can automatically be applied to arrays. The carefully-thought-out way this is done is one of the prime strengths of J. The statement

x + y

means 'add x to y'; it will do that if x and y are single numbers, or if they are multidimensional arrays. The looping needed to operate on the individual numbers is built into the language, not into your program.

I've looked at a line of J code and it's just a mess with no discernible syntax.

Something like

lifodd =. ]`[@.(2&|@[)

perhaps, a program that returns the left operand if it is odd, otherwise the right operand? Patience. Every character has a meaning, even the ` " [ ] { } characters which act individually, not as pairs. Learn what they mean and all will become clear.

I ran across this line: 1 2 + 3. What's with the extra number floating in space?

1 2 is a one-dimensional array of 2 numbers with the values 1 and 2. Arrays come up so much in J that we use this shorthand to define one without requiring any more syntax than just the values of the elements of the array.

I've looked at a line of J code and I'm absolutely sure there are no variables in it at all. How can that mean anything?

Oh, you've stumbled onto a tacit program, which describes its computation without referring to any variables, not even symbolic parameters. The classic teaching example is

mean =: +/ % #

which the mean of an array of numbers. Tacit programs are considered an advanced topic in this book, and are covered in a section at the end. They are the ultimate in

3

concise expression; many J programmers favor them for that reason, but you can wait to learn about them until you've learned simple J.

In the examples all I see are things that contain =:, which I'm guessing are assignment statements. How do I write a program?

Some of the assignment statements are programs. In J, a name becomes a function name when you assign it a value that is a function.

Once I've written a program, how do I run it? I don't see anything that looks like a function call.

In J, there is no special syntax for a function call. Just as you perform the 'minus' function with - y or the 'subtract' function with x - y, you invoke a user-defined function by typing its name before or between its operands:

x DifferenceSquared y or FindPrimeGreaterThan 1000.

How do I compile my program?

You don't. J is interpreted. As soon as you type your program in (or read it in from a file), it's ready to use. Here's a starter program:

h =: verb : '''Hello world.'''

Type that (note the triple quotes), then run it with h ''

The triple quotes are ugly.

Quit bellyaching. Read the book and you'll learn how to avoid them. Remember those 10 lines of C that were replaced by a quarter-line of J, and learn how to do that yourself.

4

Programming In J

5