You’ll never make me do that again!
I’m looking at the code and feel like an idiot. Isn’t it really an esoteric language like brain fuck? Does anyone really use it? And such programs can be read afterwards?
quicksort=: (($:@(<#[), (=#[), $:@(>#[)) ({~ ?@#)) ^: (1<#)
Perl is a trifle against it.
About J language
J — is a Korean of programming languages (may look confusing). It’s an explosion in reserved characters factory. Plenty of brackets, periods, slashes and it even works. It must be magic or something.
Wanting to be short or just having been carried away some people writing on J forget even simple rules of any code writing. These rules aren’t new but they acquire a critical meaning as applied to APL similar languages. As when reading ((]i.~[:{.[){([:{:[),]`([:<[$:[:>])@.([:32&=[:3!:0[:>]))«2 0 construction even a trained brain is at a loss.
I'll show you some simple rules of readable J code.
You should not read it without going through vocabulary.
Use Mnemonics
If you don’t like using a vocabulary or just don’t feel like looking up the symbols this or that instruction is represented by, you should convert it to a verb.
head =: {.
tail =: {:
head 9 8 3 0 6 1 2 5 4 7
9
tail 9 8 3 0 6 1 2 5 4 7
7
Divide and Rule
Sometimes it’s better to divide a complex construction into several simpler ones.
logistic =: dyad : '(^ - y % x) % x * *: >: ^ - y % x'
exp =: dyad : '^ - y % x'
logistic =: dyad : '(x exp y) % x * *: >: x exp y
Comments
J comments begin with NB., it’s exactly the case when there can’t be too much of them. If you look into standard libraries or an industrial code you’ll find hundreds of comments.
More Spaces, Different and Good Ones
An average one-liner on J consists of twenty symbols, which are weakly connected at first glance. If you locate spaces and brackets properly, they’ll help you to understand the structure of even the most complex verb.
(]%[**:@>:@])[:^[:-%~
(] % [ * *:@>:@]) [: ^ [: - %~
Obvious is Better
For complex expressions you’d better use explicit writing instead of tacit one:
(] % [ * *:@>:@]) [: ^ [: - %~
dyad : '(] % (x * *:@>:@])) ^ -y%x'
Hooks and Forks are Your Friends
If you didn’t know or forgot:
(f g) y ⇔ y f (g y)
x (f g) y ⇔ x f (g y)
(f g h) y ⇔ (f y) g (h y)
x (f g h) y ⇔ (x f y) g (x h y)
These simple structures help to shorten the code several times, without worsening its readability.
Control Structures
There are usual control structures in J, but they can be used inside an explicit verb only.
Branchings work the same way as in any other language. If T condition returned 1, we move to B block, otherwise we move to the next else./elseif. block, if it’s there.
if. T do. B end.
if. T do. B else. B1 end.
if. T do. B elseif. T1 do. B1 elseif. T2 do. B2 end.
while. and whilst. execute B block, while T returns 1, but whilst. misses the check for the first pass, so B is always executed at least once.
while. T do. B end.
whilst. T do. B end.
for. executes B as many times as there are elements in T; for_i. creates i and i_index variables — element and its index accordingly…
for. T do. B end.
for_i. T do. B end.
select. moves to the first Ti, which has concurred with T, executing the appropriate block fcase. — case. with “falling in”.
select. T
case. T0 do. B0
case. T1 do. B1
fcase.T2 do. B2
case. T3 do. B3
end.
If B block has been executed with an error then we execute B1 block, or just ignore it.
try. B catch. B1 end.
Let’s apply these rules to the following code(sudoku solver):
i =: ,((,|:)i.9 9),,./,./i.4$3
c =: (#=[:#~.)@-.&0
t =: [:(([:*/_9:c\])"1#])i&{+"1 1(>:i.9)*/[:i&=i.&0
r =: [:,`$:@.(0:e.,)[:;(<@t)"1
s =: 9 9&$@r@,
The converted code:
cells =: ,./^:2 i. 4 # 3
rows_cols =: ((, |:) i. 9 9)
indices =: , rows_cols, cells
no_errors =: verb : '(-: ~.) y -. 0'
substitutions =: verb : '(indices { y) +"1 1 ((>:i.9) */ indices = y i. 0)'
remove_wrong =: verb : 'y #~ */"(1) _9 no_errors\"1 y'
try =: remove_wrong @ substitutions
solve =: verb define
variants =: y
whilst.
0 e. ,variants
do.
variants =: ; (<@try)"1 variants
end.
,variants
)
sudoku =: verb : '9 9 $ solve , y'
Results
m
2 0 0 3 7 0 0 0 9
0 0 9 2 0 0 0 0 7
0 0 1 0 0 4 0 0 2
0 5 0 0 0 0 8 0 0
0 0 8 0 0 0 9 0 0
0 0 6 0 0 0 0 4 0
9 0 0 1 0 0 5 0 0
8 0 0 0 0 7 6 0 0
4 0 0 0 8 9 0 0 1
s m
2 8 4 3 7 5 1 6 9
6 3 9 2 1 8 4 5 7
5 7 1 9 6 4 3 8 2
1 5 2 4 9 6 8 7 3
3 4 8 7 5 2 9 1 6
7 9 6 8 3 1 2 4 5
9 6 7 1 4 3 5 2 8
8 1 3 5 2 7 6 9 4
4 2 5 6 8 9 7 3 1
sudoku m
2 8 4 3 7 5 1 6 9
6 3 9 2 1 8 4 5 7
5 7 1 9 6 4 3 8 2
1 5 2 4 9 6 8 7 3
3 4 8 7 5 2 9 1 6
7 9 6 8 3 1 2 4 5
9 6 7 1 4 3 5 2 8
8 1 3 5 2 7 6 9 4
4 2 5 6 8 9 7 3 1
Now you can see what the code’s doing. It’s quite an achievement!
Useful Links
- Official website
- Wiki
- Vocabulary — a very useful vocabulary for J study and use
- Brief Reference
- J for C programmers (pdf) — a textbook for those who are used to imperative programming
- Learning J — another textbook. There are more examples in it, and each step is described in more details, than in the previous textbook
- Puzzles — exercises
- Phrases — useful one-liner constructions
- Essays — articles about J, you’ll find more text, than code in it
- Plot — building charts with the embedded tools of J
A few more:
- Android JConsole (apk)
- Articles by Keith Smillie
- J Companion for Statistical Calculations (pdf) (ijs) — by Keith Smillie. You’ll find a brief review of the language at the beginning
- «J and OOP», by Chris Burke
- Articles at Rosetta Code wiki with examples of J usage. It’s useful for comparison with other languages. (The first 15 Catalan numbers: ((! +:) % >:) i.15x)
- J-ottings — articles by Norman Thomson about J in Vector magazine, which specializes in APL.
9 comments
Could you comment about how to handling files in J?
(There is a lot of information about sintax, verbs, and so on,
but precious little about files).
Thanks in advance
I meant how to read external files (estructured data) with the data to be used in a J program, and how to write the results to a file.
Thanks again.
By the way, that's very good you'll have a better article about J.
data will contain the content. But this is just a very simple example. Have you installed J?
One more question:
For a file with a header (about 50 lines) and the rest is numeric data (maybe a thousand lines), how to read only the first 50 lines (header), or the last 950 (data) in order to process it?
The "_2" is a flag to use the last item as the partition marker and discard it from the result; the «cut» adverb ";." boxes "<" the file into one line per box.
Upload image