J Programming FAQJ Programming FAQ 
Author Message
 J Programming FAQJ Programming FAQ

Some questions are more trivial than others - I suggest you get the J
interpreter, and read Davies's "Introduction" (see 6.1) before using this
FAQ.

Any suggestions for more FAQ-like questions (and answers) are welcome.
Contributed answers may be lightly edited.

Compiled by: Ehud Lamm
Updated    : 3/6/95
Posted to  : comp.lang.apl
Changes    : example of under, obverse, trains, rank error.

Topics:
     1. General
        1.1 What is J suited for?
|       1.2 J versions
        1.3 Is J compiled or interpreted?
        1.4 Is J APL or what?
     2. Basic Programming Questions
        2.1 What is a...
          2.1.1 verb
          2.1.2 adverb
          2.1.3 conjunction
          2.1.4 gerund
|         2.1.5 obverse function
        2.2 How to read a J expression?
        2.3 Can you please explain rank?
        2.4 What is a...
          2.4.1 Hook
          2.4.2 Fork
|         2.4.3 Train
          2.4.4 The Fit (!.) Conjunction
        2.5 Tacit definitions
|         2.5.1 Explanation
|         2.5.2 Common idioms
|    3. Examples
     4. Common Mistakes
        4.1 Wrong rank
        4.2 Dyadic or Monadic?


|       4.5 The rank of an explicit verb
     5. Interpreter Source
        5.1 How to read it?
        5.2 Can I use J from other languages (LinkJ)? How?
        5.3 Extensions available
     6. More information?
|       6.1 FTP
        6.2 The Book
        6.3 Examples on the FTP site

=============================================================================

                         A   N  S  W  E  R  S

=============================================================================
1. General
*  1.1 What is J suited for?

   J is declared as a "general purpose language". But it is evident that
   it is more suited for some things than others.
   Basically the language is from the APL family, featuring dynamically
   shaped arrays, and strong built-in array operators - no strange characters
   though....

   Today J has versions for most platforms. The source appears to be very
   portable.
   The versions of J for windows allow the programmer access to many of the
   OS services, making the environment a candidate for application design.

   Examples of known applications:

   Being a new language J currently lacks examples of known major
   applications. It should be able to replace or be added to APL applications,
   and systems.

*  1.2 J versions

   J has two main versions. Version 1, currently released as J7 is on the
   FTP site, with source code. Version 2, is for sale from ISI and has some
   important changes - notably the use of control words like if. and while. in
   explicit definition.

   Currently there is a free version of J for windows on the FTP site.

*  1.3 Is J compiled or interpreted?

   J is interpreted, but using the available source (see topic 5), you can
   add J to compiled C programs. The windows version offers other
   alternatives too - such as producing run-time diskettes and using DLLs (
   Dynamic Linked Libraries).


   J has a "compiled" intermediate form (which is a
   tree-structured representation used to represent the results
   of "tacit programming" -- see below).  J does not directly
   appear to support the full generality of the lambda calculus,

   identity functions ([ ]) which provide equivalent
   expressiveness for first order functions of one and two
   arguments.  (Most of this expressiveness is also available for
   second order functions of one or two arguments.)

   Just a thought (Ehud Lamm, again)- concerning lambda calculus, which must
   remind one of Lisp, J has $: (self-reference) and  : , which allow
   anonymous functions (that is, verbs...)

*  1.4 Is J APL or what?

   J is defined to be a dialect of APL (see the "dictionary"). APL programmers
   should find the language very familiar. There are differences though, that
   are of interest.

   * ASCII - J uses only normal ascii characters to encode its operators.
   * RANK - the notion of rank, which replaces the "axis specifier" of APL
     operators is applicable to each and every verb. This allows a much easier
     use of certain operators, and makes the underlying notions of the
     language more universal.
   * BOXing - the notions of boxed arrays (nested structures) wasn't
     introduced with J. However in J it is a basic part of the language, and
     following Sharp APL (I think) BOX always produces a result differing from
     its argument (even if scalar).

   (anything more to add to this list?)

=============================================================================
2. Basic Programming Questions
   2.1 What is a...
*       2.1.1 verb

        What other languages commonly refer to as an operator, is called a
        verb in J.
        A verb may be defined implicitly using tacit definitions (see 2.5)
        or explicitly using the dyadic conjunction :

*       2.1.2 adverb

        Adverbs modify the behavior of a verb. The best example is insert
        ( / ) which places the verb between the elements of the operand (noun)
        For example +/ 1 2 3 means 1+2+3

        Adverbs like verbs may be defined by the programmer. This is one of
        the great aspects of J.
        (more on this later)

*       2.1.3 conjunction

        A conjunction is used to create a new verb using existing verbs.

        u to the result of applying v to the argument. This is a basic tool
        in tacit definitions (2.5)

        Basic conjunctions:

        &  - bond (fix an argument to a verb. +&5 is "add 5")
             This is not the only use.
        &. - under (see example of under in section 3)
        "  - Rank (see 2.3)
        ^: - Power f^:n x if f(f(f(..f(x)))) nesting level of n.
             f^:_ gives the limit of applying f like this. Negative n gives
             the same for the obverse (usually this is the inverse) function.
             (see 2.1.5)

             See 2.1.4 below.

        (are these really the basic ones??)

*       2.1.4 Gerunds

        Gerunds the dictionary says are "nouns that carry the force of a verb"
        They are produced using the tie (`) conjunction, and can later be
        used as something like "case" statements in other languages. You can

        a gerund f'g. Perhaps a better analogy is arrays of functions...


        to the arguments. This is best understood monadically.
        Suppose we want an expression that will square any number lower than
        5 and will give the square root otherwise. Our two options are *: and
        %: , and our criteria is >&5.
        Define cond=.>&5. Now cond 10 is 1 and cond 3 is 0. This means that
        in our gerund we need *: as the zeroth element and %: as the element
        in position 1. So we define gerund=.*:`%:


        *: from the gerund is applied to 3 and the final result is 9. Voila..

        Note: Since both the condition and the verb from the gerund get the
        same arguments, it is at times necessary to use [,] ~ etc. to make
        adjustments. Also watch out for "domain errors".

   Some conjunctions and adverbs accept gerunds.
   -    ^: (power) - from the Dictionary:
        x u^:(v0`v1`v2) y <==> (x v0 y) u^: (x v1 y) (x v2 y)
        x u^:(   v1`v2) y <==> x u^: ([`v1`v2) y
          u^:(   v1`v2) y <==> u^: (v1 y) (v2 y)

   -    / (insert) - Inserts successive verbs from the gerund, which may be
        extended cyclically.

   -   /. (oblique) - Applies each verb from the gerund to each item of the
       argument. *:`%: /. 9 ==> 81 3.
       Dyadic meaning is the same (pairs of corresponding items).

*       2.1.5 obverse function

        The "obverse function" is used in J to refer to the inverse function.
        This is the verb applied in such cases as v^:_n (see 2.1.3), and with
        the under conjunction (see 3).
        J has several ways to select the obverse. Many built-in verbs have
        obverse verbs (for example *: is the obverse of %:). J also knows how
        to deal with monadic verbs like 3&+.

        which will not be discussed here.

        You can specify an explicit obverse using the :. conjunction

        u b. _1 gives the obverse of u.

        Example:
        (+ :. -) b. _1   ==> - :. +

*  2.2 How to read a J expression?

   Rule 1: Remember that expressions are evaluated right to left, and
           with no precedence.
           1 * 2 - 3 % 4 ==> 1 * (2 - (3 % 4))
   Rule 2: Remember to find the hooks and forks, conjunctions adverbs etc.

           *(+/)  1 _2 3 ==> *(+/ 1 _2 3) which is the same thing
           (*(+/)) 1 _2 3==> the hook (*(+/)) applied to 1 _2 3 this is
                             1 _2 3 * (+/ 1 _2 3) which is different!!
           (*+/) 1 _2 3  ==> use rule one to read (*+/) and see that it is
                             just (*(+/)) again!!
   Rule 3: When in doubt use the display representation.
           if you write to J *+/ it will output:
           +---+------------+
           | * | +---+---+  |
           |   | | + | / |  |
           |   | +---+---+  |
           +---+-+---+---+--+
           which show you how to read it: the hook of * and +/
           Try this on other verbs and check the results. This can be very
           useful.
   Rule 4: When in grave doubts use the tree representation.
           (will be added soon)
   Rule 5: You can tell if a verb is to be used dyadically or monadically only
           from context.

*  2.3 Can you please explain rank?


        Rank is the mechanism used to control J's implicit looping.
        If you do not wish to have J implicitly loop over the elements
        of an array, you must ensure that the rank of the function
        is greater than or equal to the rank of the array.  [The rank
        of an array is how many dimensions it has.]

        (define k-cells,prefix, items)

        For example,
        a=: i. 2 3 5 7  NB. a rank 4 array
    #"4 a   NB. This is from [2]-3-5-7, two 3-5-7 arrays.
2
    #"3 a   NB. This comes from (2)-[3]-5-7, we now have 2 arrays of 3 (5*7)
            NB. arrays. ($ #"3 a) = 2
3 3
    #"2 a   NB. Now we look at (2*3) of 5 arrays of arrays of shape 7
5 5 5
5 5 5

    #"1 a   NB. Can you now tell what this has to be?

        The rank conjunction (") may have up to three numbers for its
        right argument.  These indicate Singular, Left, and Right
        rank.  If only two numbers are provided, they indicate Left
        and Right rank.

        Infinity (_) is a valid number here.  Negative numbers are
        treated as offsets from the argument array's size.  Here's
        some convenient usages of rank:

        f"_       NB. don't loop except as provided in definition of f
                      (useful for further derivation using f).
        f"_ _1    NB. loop over items of right argument
        f"_1 _    NB. loop over items of left argument
        f"_1      NB. loop over items of any argument

   2.4 What is a...
*       2.4.1 Hook

        A hook is the verb resulting from the expression f g where both f and
        g are verbs. Examples: *+ , *+/ (see 2.2) etc.

        Monadic meaning: (f g) x means x f (g x)
        Example: ** x means x * (*x) which is x times the sign of x.
                 This clearly gives the absolute value of x.

        Dyadic meaning:  x (f g) y means x f (g y)
        Example: (nice example to be added here)

        Hooks have infinite rank.

*       2.4.2 Fork

        A fork is made up of three verbs f g h.

        Monadic meaning: (f g h) x means (f x) g (h x)
        Example: +/ % #  means sum (+/) divided (%) by number of elements (#)
                This simply is arithmetic mean. (+/ % #) 1 2 3 4 is 10 % 4
                which is 2.5

        Dyadic meaning: x (f g h) y means (x f y) g (x h y)
        Example: (nice example to be added here)

        Forks have infinite rank.

*       2.4.3 Train

        "An isolated sequence such as (+ */) which the 'normal' parsing rules
        (other than the three labelled trident and bident) do not resolve to a
        single part of speech is called a train and may be further resolved"
        (J Dictionary sec. F)

        Trains of any length are broken into trains of two (bidents) or three
        (tridents) elements. The J dictionary lists the meaning or each
        possible bident and trident. For example the trident v0 v1 v2, made of
        three verbs is a fork (see 2.4.2).

        It is important to remember this part of J parsing, even though many
        tridents and bidents occur only rarely.

*       2.4.4 The Fit (!.) Conjunction

        The fit conjunction is an ad-hoc feature that allows altering the
        behavior of some verbs. It is mainly used to alter the tolerance of
        comparisons (e.g. =,<,<: etc.) and to choose a fill element where one
        is needed  ($,|.,#,{. when used dyadically).

        Example of tolerance:
          m=.123456789002        NB. check number of digits...
          l=.123456789001
          m=l           ==> 0
          m =!.1e_11 l  ==> 1

        Examples of fill:
          l=. 1 2 3 4
          1 |.    l  ==> 2 3 4 1 (cyclic rotation)
          1 |.!.0 l  ==> 2 3 4 0 (left shift)
          1 |.!.''l  ==> 2 3 4 0 (empty argument to !. chooses default fill
                                  element - in rotate - zero for numeric
                                  arguments)

          (3j4) # 4        ==> 4 4 4 0 0 0 0 (3 copies, 4 fills)
          (3j4) (#!._1) 4  ==> 4 4 4 _1 _1 _1 _1

   2.5 Tacit definitions
*       2.5.1 Explanation

        Tacit definitions are the most remarkable feature of J. They make the
        language a *functional language*. They are the basic tool used to
        program in J.

        Any assignment whose right hand side is a verb, creates a pro-verb,
        which can be used in its stead. For example you can define PLUS=.+
        and from now on use PLUS instead of + in any expression. This is
        basically a tacit definition. New adverbs may be defined too.

        A tacit definition may be much more complicated, and made of longer
        and more intricate expressions. It can be made up of hooks, forks
        conjunctions adverbs etc.
        For example am=. +/ % # assign to am the fork +/ % #. This is a
        tacit definition of arithmetic mean (see 2.4.2).

        The thing that makes this definition tacit is that nowhere in it do
        we explicitly refer to the arguments. We do not change them, copy
        etc. The verb defined is a fork, so it will act as a fork (see 2.4.2)

        Explicit definitions are also possible in J, using the conjunction :
        am can be explicitly defined like this:
        am=. (+/ y.) % (# y.) : 'Only monadic defined '

        This means that the verb am when used monadically will refer to the
        expression (+/ y.) % (# y.) where y. is the right (and only) argument.
        When used dyadically am will result in the string "Only monadic defined
        Had we wished to use the left argument in the dyadic definition we
        could have used x. .

        This kind of definition, with explicit use of the arguments x., y. is
        not functional, and is not referred to as tacit.

        In J2 one can use control words like while. and if. in explicit
        definitions.

        Functional programming takes some getting used to. You have to
        eliminate almost all variables (nouns) from your expressions, and
        use functions (verbs) instead. The idea is not to mutate (i.e, change)
        nouns - just to return a modified value.

        The basic tools of tacit definition:


                        see 2.1.3

        * Use constant functions (0: etc.) to aid programming in a functional
          style.

        * [ and ] which are verbs that return their left and right
                  arguments respectively.

        * ~ (nub) which when applied dyadically switches the arguments
                  (left <-> right) and monadically duplicates the argument as
                  both the right and left argument.
                  Examples:
                       1. ;~(>:i.6) ==> (>:i.6);(>:i.6)

                       2. ^~ (dyadic) is the same as ]^[

        (any more basic tools?)

*       2.5.2 Common idioms

        APL and J are not ordinary imperative languages!! They are built
        around some basic concepts that are at times hard to grasp. J and
        APL programmers develop for their own use certain common "idioms" that
        help them program. These serve two purposes: (1) They make it easier
        to program since your basic "vocabulary" is larger. (2) They help
        others read what you wrote, since you use the same idiomatic phrases
        for common operations.
        So even if you know how to do something, it is better to use the
        common idioms. This is intended to be a list of such idioms.

        * See the rank uses in question 2.3

                      the left and right argument.
        * v arg [ comment : used to add comments. The expression is the same
                      as v (arg [ comment) which is just v arg.
                      Note: the 'comment' part is executed, but only for
                      side effects.
        * [ used to put "sequence points". For example f^:10 10 will not be
          understood correctly because it is parsed as f^:(10 10), however
          f^:10 [ 10 works just fine. Shorter than (f^:10) 10
        * [a=. expr : to see the value of an assignment.
        * Using # with a mask to choose elements. Dyadically # means copy,
          that is 3 4 2 # vec results in a vector consisting of three times
          the first element of vec, 4 times the second and 2 times the third.
          Thus if the number of times to copy is boolean (0 or 1) the result
          consists of those elements which have 1 in the corresponding place
          in the mask. 1 0 1 # 2 3 4 ==> 2 4
        * &.> adverb to invoke a verb for each cell in a boxed argument.
          (see Q3, example 2)

        (please send more idioms...)
=============================================================================
3. Examples

One of the basic things needed in order to master a programming language is
examples. J has some problems in this respect. (1) Being a new language and
not just another C variant, there aren't many books and articles on J. (2)
Since reading a J expression can be a trying experience at first it is hard
to give examples which are easy enough to be understood yet interesting
enough to make the effort worth-while. In this section I will try to offer
short examples which I found to be helpful. This list should not grow in size,
it should contain the best available short examples.

Example 1 - IF
--------------
People with a background of C and Pascal usually miss if. In J2 they can use
if. in explicit definitions. Many times J offers alternatives. Here we will
show the use of gerunds instead of if. in defining the function half-or-triple-
plus-one. This function halves its argument if it is even, and returns 1+3*y.
otherwise. This function is remarkable because when repeatedly applied to any
argument it leads to the result of 1. That is for any positive integer k
there exists some positive integer l for which (f^:l k) = 1.
This is not a proven fact, however.

Explicit definition:

odd=.2&|    NB. Check if argument is odd

h=. 3 : 0
if. odd y.
    do.
       (3*y.) + 1
    else.
       -: y.
end.
)

The J way:



Example 2 - &. (under,dual)
---------------------------
u&.v is the same as u&v except that the function obverse to v is applied to
each cell of the result. The most common use is "opening" boxed arrays.

sum=.+/
box=.1 2 3;4 5           NB.  box is boxed like this [1 2 3][4 5]
sum box    ==> domain error


sum&.>  box==> [6][9]    NB.  same as the above

=============================================================================
4. Common Mistakes
*  4.1 Wrong rank

   See question 2.3.
   Rank is one of the most important concepts of J. It is highly probable
   that your first problems with J will come from it.
   A couple of things to remember:

     * A conjunction's rank depends not only on the verbs but also on the

       and &: are similar.

     * You can see the rank of a verb using "basic characteristics" (b.)
       e.g. + b. 0 ==> _ 0 0 which are the monadic, left and right ranks
       of + .

*  4.2 Dyadic or Monadic?

   See reading rule 5. Also remember that if you define a verb explicitly,
   you can use the form v=. what-ever : '' or v=. '': what-ever to ensure
   the verbs have only monadic or dyadic meaning. The other form will only
   cause an error.

   Note: The above definition of v is incorrect in J2. Explicit definitions
         in J2 are a bit more elaborate.
         Use v=. 3 : (what-ever;':';'') instead of the above.


   One of the basic problems for newcomers is knowing when to use a hook, a
   fork or the atop conjunction. It is crucial to know when you can take

   can get confusing; especially when dyadic verbs are concerned.
   Remember to use the reading rules, and to know when you actually are seeing


   See 4.1...

*  4.5 The rank of an explicit verb

   A verb defined using the : conjunction has unbounded rank. The reason is
   that a verb having unbounded rank can be used without thinking of its
   rank. All you have to do is to apply the rank you want to it.
   For example if f has unbounded rank, f"r will always work correctly on
   rank r cells. For more see Q2.3 .

   Forgetting this can lead to confusion. For example:
   m=. 3 : ('';':';'x.+y.')    NB. (J2). m should be like +
   1 2 3 m 3 4 5               NB. ==> 4 6 8. So far so good.
   1 2 3 m/ 3 4 5              NB. ==> 4 6 8. No table? What's wrong?
   m b. 0                      NB. ==> _ _ _. m has infinite rank.
   1 2 3 (m"0)/ 3 4 5          NB. Works as expected.

   NB. Another way:
   m=. 3 : ('';':';'x.+y.')"0
   1 2 3 m/ 3 4 5              NB. Just as m"0 above.

=============================================================================
5. Interpreter Source
*  5.1 How to read it?

   The J source is dense! Beware!
   The J source makes heavy use of C macros. The main ones are in the files
   J.H, JT.H.
   Take note of F1 and F2 which are used to declare almost all the functions
   in the source (and declare the a and w parameters), and R,RE and RZ which
   are used to "return".

   After reading these files, you can start to read the actual C, but it is
   wise to look at all relevant h files before trying to read the c files,
   since, and I iterate, there is a great use of macros. A good suggestion is
   to use a preprocessor before trying to read the source.

   Reading the source, remember to distinguish between the files of the
   interpreter itself, the files implementing the J verbs, adverbs and
   conjunctions, and the interpreter utility functions.

   (more to be added here)

*  5.2 Can I use J from other languages (LinkJ)? How?


   You can take several approaches :

   1. Since you are programming on a DOS box you probably have Windows 3.1
   around and you'd be wise to use J Release II.04 for Windows.

   With that you can call C function have been built into DLLs
   (Dynamic Link Libraries).

   With this approach, the complications of calling C from J
   involve the specifics of building DLLs with your C compiler.

   I haven't had the time to experiment with this interface so
   I can't post any examples. The on-line documentation is comprehensive
   but does not provide an example. I imagine that Chris Burke
   will cook up some example which will come with the next release
   of J.

   2. Now, suppose you are compiling the J source (available at watserv1)
   from scratch to build your own interpreter. Here you have
   additional freedom because you can use the functions of the
   J source. In fact, it is possible to translate J into C.
   In the fftpack and lapack stuff at watserv1 I used functions
   from the J source in the wrapper to call f2c'd fortran.

   3. Also, regarding J for Windows there is another approach
   which I'm a bit e{*filter*}d about. That is, you can compile your
   own J interpreter, but instead of building it as an .EXE (executable file),
   build it as a DLL.  Then replace the DLL provided by ISI
   with your own.

   If you go all out and purchase the JII source you can have the
   best of both worlds, the capability to use the functions in the
   J source (so you can translate some J into C) AND to call C from
   DLLs.

   I'm e{*filter*}d about all this because this will let you use J
   as a tool for building GUIs (Graphic User Interface), graphing, handling
   DLLs, DDE (Dynamic Data Exchange), and ODBC (Open Data-Base Connectivity).
   Programmers don't have to learn all the in and outs of the Windows API or
   many of the different Windows system calls to build custom applications.
   You can build your own C stuff, integrate it into a new J interpreter and
   your all set.

   On the other hand, ISI might be reluctant to have there be
   competing version of the J interpreter out there and I haven't
   yet been able to build my own DLL and call it from the session
   manager. So I can't say for certain whether this approach
   can work without help from ISI.

   Regarding C compilers :

   ISI uses a WATCOM C compiler for the interpreter to build
   a 32 bit interpreter and VC++ to build a 16 bit session manager.

   If you go into js.h you can see which compiler is recommended
   for each platform. For the PC it says Turbo C.

   Somewhere in the archives there is an old post of Rogers about
   the suggested setting on your machine for compiling under Turbo C.

   Regarding an interface to Pascal :

   My understanding is that you can call Pascal if your Pascal
   compiler will let you build DLLs. Then you'd need either
   JII for Windows or the source to JII.04 to call them.

   Other than that I'd say if you are currently able to call
   Pascal from C then there is every reason to believe that
   you can call Pascal from J provided you compile your own
   J interpreter with you favorite C compiler.

   (Thanks, Emmet. If anyone has other examples let me know).

*  5.3 Extensions available

   See 5.2 for a reference to Emmet Mclean's extensions available at watserv1
   This is the place to look for other extensions too.
   If any one has pointers to other extensions, or a list of what is
   available (I think Emmet posted something like that some time ago) let me
   know.

=============================================================================
6. More information?
   The basic J-FAQ has most of the information below too. So this part is
   meant to be only a starting point.

*  6.1 FTP

   The "official" FTP site is watserv1.waterloo.edu. The directory is
   languages/apl/j
   I urge you to browse there as one of your first steps.
   Of course the source can be FTPed from there, as well as the free version
   for windows, and the J manuals in windows help file format.

   For Kieth Smillie's "Some Notes on Introducing J with Statistical Examples"
   FTP to ftp.cs.ualberta.ca

   You may find Harvey Davies's "Introduction to J" useful; it is also here.

*  6.2 The Book

   The basic book on J is the "J Introduction and Dictionary" by Iverson.
   Available as part of the J package. To order contact Iverson Software.

*  6.3 Examples on the FTP site
   (to be added)

--



Wed, 19 Nov 1997 03:00:00 GMT  
 
 [ 1 post ] 

 Relevant Pages 

1. JS for functional programming?

2. JS for functional programming?

3. JS-EAI with *JS*-callback

4. js.exception 3279.js

5. J programming faq

6. J programming FAQ - possible outline

7. FAQ for A Programming Language (APL), where?

8. Forth Programming Language FAQ: Part 1 of 6, General Information

9. Forth Programming Language FAQ: Part 1 of 6, General Information

10. Forth Programming Language FAQ: Part 1 of 6, General Information

11. Forth Programming Language FAQ: Part 6 of 6, Forth Groups

 

 
Powered by phpBB® Forum Software