
- •Foreword
- •1. Introduction
- •2. Culture Shock
- •3. Preliminaries
- •Notation Used in This Book
- •Terminology
- •Sentences (statements)
- •Word Formation (tokenizing rules)
- •Numbers
- •Characters
- •Valence of Verbs (Binary and Unary Operators)
- •How Names (Identifiers) Get Assigned
- •Order of Evaluation
- •How Names Are Substituted
- •What a verb (function) looks like
- •Running a J program
- •The Execution Window; Script Windows
- •Names Defined at Startup
- •Step-By-Step Learning: Labs
- •J Documentation
- •Getting Help
- •4. A First Look At J Programs
- •Average Daily Balance
- •Calculating Chebyshev Coefficients
- •5. Declarations
- •Arrays
- •Cells
- •Phrases To Memorize
- •Constant Lists
- •Array-creating Verbs
- •6. Loopless Code I—Verbs Have Rank
- •Examples of Implicit Loops
- •The Concept of Verb Rank
- •Verb Execution—How Rank Is Used (Monads)
- •Controlling Verb Execution By Specifying a Rank
- •Examples Of Verb Rank
- •Negative Verb Rank
- •Verb Execution—How Rank Is Used (Dyads)
- •When Dyad Frames Differ: Operand Agreement
- •Order of Execution in Implied Loops
- •A Mistake To Avoid
- •7. Starting To Write In J
- •8. More Verbs
- •Arithmetic Dyads
- •Boolean Dyads
- •Min and Max Dyads
- •Arithmetic Monads
- •Boolean Monad
- •Operations on Arrays
- •9. Loopless Code II—Adverbs / and ~
- •Modifiers
- •The Adverb Monad u/
- •The adverb ~
- •10. Continuing to Write in J
- •11. Boxing (structures)
- •Terminology
- •Boxing As an Equivalent For Structures In C
- •12. Compound Verbs
- •Verb Sequences—u@:v and u@v
- •Making a Monad Into a Dyad: The Verbs [ and ]
- •Making a Dyad Into a Monad: u&n and m&v
- •13. Empty Operands
- •Execution On a Cell Of Fills
- •Empty cells
- •If Fill-Cells Are Not Enough
- •14. Loopless Code III—Adverbs \ and \.
- •15. Verbs for Arithmetic
- •Dyads
- •Monads (all rank 0)
- •16. Loopless Code IV
- •A Few J Tricks
- •Power/If/DoWhile Conjunction u^:n and u^:v
- •Tie and Agenda (switch)
- •17. More Verbs For Boxes
- •Dyad ; (Link) And Monad ; (Raze)
- •Dyad { Revisited: the Full Story
- •Split String Into J Words: Monad ;:
- •Fetch From Structure: Dyad {::
- •Report Boxing Level: Monad L.
- •18. Verb-Definition Revisited
- •What really happens during m :n and verb define
- •Compound Verbs Can Be Assigned
- •Dual-Valence verbs: u :v
- •The Suicide Verb [:
- •Multi-Line Comments Using 0 :0
- •Final Reminder
- •The Obverse u^:_1
- •Apply Under Transformation: u&.v and u&.:v
- •Defined obverses: u :.v
- •An observation about dyadic verbs
- •20. Performance: Measurement & Tips
- •Timing Individual Sentences
- •Compounds Recognized by the Interpreter
- •Use Large Verb-Ranks! and Integrated Rank Support
- •Shining a Light: The J Performance Monitor
- •21. Input And Output
- •Foreigns
- •File Operations 1!:n; Error Handling
- •Treating a File as a Noun: Mapped Files
- •Format Data For Printing: Monad And Dyad ":
- •Format an Array: 8!:n
- •Format binary data: 3!:n
- •printf, sprintf, and qprintf
- •Convert Character To Numeric: Dyad ".
- •22. Calling a DLL Under Windows
- •Memory Management
- •Aliasing of Variables
- •23. Socket Programming
- •Asynchronous Sockets and socket_handler
- •Names and IP Addresses
- •Connecting
- •Listening
- •Other Socket Verbs
- •24. Loopless Code V—Partitions
- •Find Unique Items: Monad ~. and Monad ~:
- •Apply On Subsets: Dyad u/.
- •Apply On Partitions: Monad u;.1 and u;.2
- •Apply On Specified Partitions: Dyad u;.1 and u;.2
- •Apply On Subarray: Dyad u;.0
- •Apply On All Subarrays: Dyad u;.3 and u;._3
- •Extracting Variable-Length Fields Using ^: and ;.1
- •Example: Combining Adjacent Boxes
- •25. When Programs Are Data
- •Calling a Published Name
- •Using the Argument To a Modifier
- •Invoking a Gerund: m`:6
- •Passing the Definition Of a Verb: 128!:2 (Apply)
- •Passing an Executable Sentence: Monad ". and 5!:5
- •26. Loopless Code VI
- •28. Modifying an array: m}
- •Monad I.—Indexes of the 1s in a Boolean Vector
- •29. Control Structures
- •while./do./end. and whilst./do./end.
- •if./do./else./end., if./do./elseif./do./end.
- •try./catch./catcht./end. and throw.
- •return.
- •assert.
- •30. Modular Code
- •Locales And Locatives
- •Assignment
- •Name Lookup
- •Changing The Current Locale
- •The Shared Locale 'z'
- •Using Locales
- •31. Writing Your Own Modifiers
- •Modifiers That Do Not Refer To x. Or y.
- •Modifiers That Refer To x. Or y.
- •32. Applied Mathematics in J
- •Complex Numbers
- •Matrix Operations
- •Calculus: d., D., D:, and p..
- •Taylor Series: t., t:, and T.
- •Hypergeometric Function with H.
- •Sparse Arrays: Monad and Dyad $.
- •Random Numbers: ?
- •Computational Addons
- •Useful Scripts Supplied With J
- •33. Elementary Mathematics in J
- •Verbs for Mathematics
- •Extended Integers, Rational Numbers, and x:
- •Factors and Primes: Monad p:, Monad and Dyad q:
- •Permutations: A. and C.
- •34. Graphics
- •Plot Package
- •2D Graphics: the gl2 Library
- •Displaying Tabular Data: the Grid Control
- •3D Graphics: OpenGL
- •35. Odds And Ends
- •Dyad # Revisited
- •Boxed words to string: Monad ;:^:_1
- •Spread: #^:_1
- •Choose From Lists Item-By-Item: monad m}
- •Recursion: $:
- •Make a Table: Adverb dyad u/
- •Cartesian Product: Monad {
- •Boolean Functions: Dyad m b.
- •Operations Inside Boxes: u L: n, u S: n
- •Comparison Tolerance !.f
- •Right Shift: Monad |.!.f
- •Generalized Transpose: Dyad |:
- •Monad i: and Dyad i:
- •Fast String Searching: s: (Symbols)
- •Fast Searching: m&i.
- •CRC Calculation
- •Unicode Characters: u:
- •Window Driver And Form Editor
- •Tacit Programming
- •36. Tacit Programs
- •37. First Look At Forks
- •38. Parsing and Execution I
- •39. Parsing and Execution II
- •The Parsing Table
- •Examples Of Parsing And Execution
- •Undefined Words
- •40. Forks, Hooks, and Compound Adverbs
- •Tacit and Compound Adverbs
- •Referring To a Noun In a Tacit Verb
- •41. Readable Tacit Definitions
- •Flatten a Verb: Adverb f.
- •Special Verb-Forms Used in Tacit Definitions
- •43. Common Mistakes
- •Mechanics
- •Programming Errors
- •44. Valedictory
- •45. Glossary
- •46. Error Messages
- •47. Index
11. Boxing (structures)
The nouns we have encountered so far have all had items with identical shapes, and with all atoms of the same type, either numeric or character. You may be afraid that such regular arrays are all that J supports and that you will have to forgo C structures; and you may wonder how J will fare in the rough-and-tumble of the real world where data is not so regular. This chapter will put those fears to rest.
I think we should get a formal understanding of boxing in J before we try to relate it to structures in C, because the ideas are just different enough to cause confusion. The box is an atomic data type in J, along with number and character. As with the other types, a single box is a scalar, with rank 0 and empty shape. Just as a numeric or character atom has a value, so a boxed atom has a value, called its contents. The box is special in that its contents can be an array while the box itself is an atom. The boxing protects the contents and allows them to be treated as an atom.
Arrays of boxes are allowed, and as always all the atoms in an array must have the same type: if any element is boxed, all must be boxed.
Various verbs create boxes. Monad < has infinite rank and exists for the sole purpose of boxing its operand: < y creates a box whose contents are y, for example:
<1
+-+ |1| +-+
<1 2 3 +-----+ |1 2 3| +-----+
<'abc' +---+ |abc| +---+
When a box is displayed, the contents are surrounded by the boxing characters as seen in the examples.
Only certain primitives can accept boxes as operands; generally, you cannot perform arithmetic on boxes but you can do other things like monad and dyad #, monad and dyad $, and other primitives that do not perform arithmetic. The significant exception to this rule is that you can use monad and dyad /: and \: to order boxed arrays. Comparison for equality between two atoms is not strictly an arithmetic operation—you
can compare two characters or a character and a number for equality, for example—and it is allowed on boxes, both explicitly using dyad = and dyad -:or implicitly using
dyad i. and dyad e.; but there is an arithmetic flavor to the operation: if the contents of corresponding components of the boxes are both numbers, tolerant comparison is used.
76
Most primitives that accept boxes as operands do not examine the contents of the boxes, but instead perform their operation on the box atoms themselves. Any deviation from this behavior will be noted in the definition of the verb (we have not encountered any yet). Examples:
3 $ <'abc' +---+---+---+ |abc|abc|abc| +---+---+---+
The dyad $ was applied to the box, creating a list of identical boxes.
(<1 2),(<5),(<'abc') +---+-+---+
|1 2|5|abc| +---+-+---+
The boxes were concatenated, resulting in a list of boxes. Note that the contents of the boxes do not have to have the same shape or type.
1 0 1 # (<1 2),(<5),(<'abc') +---+---+
|1 2|abc| +---+---+
The selection performed by dyad # is performed on the boxes, not on their contents.
Since applying a verb may result in the addition of verb fills and framing fills, we need to meet the fill element used for boxed nouns. It is the noun a: . a: is defined to be <0$0, i. e. an atom which is a box containing an empty numeric list (note that this is not the same thing as a box containing an empty string or an empty boxed list).
a:
++
||
++
3 {. <5 +-+++
|5||| +-+++
a:was used for the fills added by overtaking from this boxed noun.
The contents of a box can be any noun, including a box or array of boxes:
77
< < 2 3 |
||
+----- |
+ |
|
|+--- |
+| |
|
||2 |
3|| |
|
|+--- |
+| |
|
+----- |
+ |
|
(<'abc'),(<<1 2) |
||
+--- |
+----- |
+ |
|abc|+--- |
+| |
|
| |
||1 2|| |
|
| |
|+--- |
+| |
+--- |
+----- |
+ |
The contents of a box can be recovered by opening the box with monad > . Monad > has rank 0 (since it operates only on boxes, which are atoms), and its result is the contents of the box:
> < 'abc'
abc
The contents of the box is the character string. a =. (<1 2),(<<5),(<'abc') > 0 { a
1 2
> 1 { a
+-+ |5| +-+
Here we recover the contents of the selected box (which may be a box).
> (<1 2 3),(<4) 1 2 3 4 0 0
Remember that monad > has rank 0, so it is applied to each box and the results are collected using the frame. Here framing fills were added to the shorter result. 0 was used as the framing fill because the contents of the boxes were numeric.
>a |domain error | >a
Here the results on the different cells were of different types, so it was impossible to collect them into an array.
If y is unboxed, the result of > y is y .
Terminology
Before we go further with boxes, let's agree on some terminology. Because every atom in an array must have the same type, it is reasonable to speak of an array as being 'boxed' if its atoms are boxed, 'unboxed' otherwise (some writers use 'open' as a synonym for 'unboxed'). Trouble arises with a phrase like 'boxed list'. If I box a list (e. g.
<1 2 3), does that give me a boxed list? If I have a list whose atoms are boxes, (e. g.
78
(<1),(<2)), is that also a boxed list? Unfortunately, writers on J have not agreed on terminology for these cases.
In this book, a boxed list will be a list that has been put into a box (it is therefore an atom), and a list of boxes is a list each atom of which is a box. Higher ranks are described similarly. If we say that a noun 'is boxed', that simply means that its atoms are boxes.
Boxing As an Equivalent For Structures In C
A C struct corresponds to a list of boxes in J, where each box in the list corresponds to one structure element. Referencing a structure element in C corresponds to selecting and opening an item in J. For example,
struct {
int f[ ] = {1,2,3}; char g[ ] = "abc"; float h = 1.0;
)
is equivalent to
(<1 2 3) , (<'abc') , (<1.0)
A C n-dimensional array of structures is equivalent to a J array of boxes of rank n+1. The last axis of the J array corresponds to the structure, and its length is the number of structure elements in the C structure.
C has no exact equivalent for a single box.
79