Ch 26: Script Files

| # Chapter 26: Script Files A file containing text in the form of lines of J is called a script-file, or just a script. By convention a script has a filename terminating with `.ijs` . The process of executing the lines of J in a script-file is called "loading" a script. We write our own scripts for our particular programming projects. In addition, the J system comes supplied with a library of predefined scripts of general utility. The plan for this chapter is to look at built-in verbs for loading scripts the `load` verb and its advantages, including convenient loading of library scripts the "profile" script automatically loaded at the beginning of a J session ## 26.1 Creating Scripts It is useful to begin by identifying a directory where we intend to store our own scripts. For example, with Linux we could say:
        scriptdir =: '/home/username/scripts/'
(Notice that last character). With Windows we could say:
        scriptdir =: 'c:\scripts\'
Scripts are usually created using a text editor, but here it is convenient to use J to create small examples of scripts as we need them. Here is an example of creating a tiny script, with a filename of say `example.ijs`, using the built-in verb `1!:2` thus:
       (0 : 0) (1!:2) < scriptdir,'example.ijs'
    plus =: +
    k    =: 2 plus 3
    k plus 1
    )
## 26.2 Loading Scripts There is a built-in verb `0!:1` to load a script. The argument is a filename as a boxed string.
       0!:1 < scriptdir,'example.ijs'
       plus =: +
       k    =: 2 plus 3
       k plus 1
    6
We see on the screen a display of the lines of the script as they were executed, together with the result-values of any computations. The definitions of `plus` and `k` are now available:
`plus` | `k`
    +
    5
The verb `0!:1`, as we saw, loads a script with a display. We can choose whether or not to display, and whether to stop or to continue loading after an error. There are four similar verbs:
`0!:0` | no display | stopping on error
`0!:1` | with display | stopping on error
`0!:10` | no display | continuing on error
`0!:11` | with display | continuing on error
For example:
       0!:0 < scriptdir,'example.ijs'
We see nothing on the screen. The value computed in the script for `k plus 1` is discarded. ## 26.3 The load Verb There is a verb `load` which is predefined, that is, automatically available in the standard J setup. It can be used just like `0!:0` to load a script
       load < scriptdir,'example.ijs'
The script is loaded without a display and stopping on error. There is a companion verb `loadd` which loads with a display, stopping on error.
       loadd < scriptdir, 'example.ijs'
       plus =: +
       k    =: 2 plus 3
       k plus 1
    6
`load` and `loadd` have several advantages compared with `0!:n` . The first of these is that the filename need not be boxed.
       loadd scriptdir, 'example.ijs'
       plus =: +
       k    =: 2 plus 3
       k plus 1
    6
## 26.4 Library Scripts The second advantage of `load` is that it is convenient for loading "library" scripts. The J system comes supplied with a useful library of script files containing predefined utility functions and documentation. Library script files are organized in a set of directories under the J installation directory. There is a catalog of library scripts, stored in a variable, a table called `PUBLIC_j_` . The following shows a few "catalog entries" in rows 15-17 of `PUBLIC_j_`
       15 16 17  { PUBLIC_j_
    +------+---------------------------------------+
    |files |/home/book/j501b/system/main/files.ijs |
    +------+---------------------------------------+
    |format|/home/book/j501b/system/main/format.ijs|
    +------+---------------------------------------+
    |gl2   |/home/book/j501b/system/main/gl2.ijs   |
    +------+---------------------------------------+
We see for each library script a "short name" (for example, `'files'`) and a full filename for the script. The `load` verb can load a library script given the short name.
       load 'files'
Now we have available a set of utility functions for handling files, for example, `fwrite`.
       fwrite
    4 : 0
    y=. boxopen y.
    dat=. ,x.
    f=. #@[ [ 1!:2
    dat f :: _1: y
    )
## 26.5 Local Definitions in Scripts Now we look at the treatment of local variables in scripts. Here is an example of a script.
       (0 : 0) (1!:2) < scriptdir, 'ex1.ijs'
    w   =: 1 + 1
    foo =: + & w
    )
Suppose that variable `w` has the sole purpose of helping to define verb `foo` and otherwise `w` is of no interest. It would be better to make `w` a local variable. Firstly, we need to assign to `w` with `=.` in the same way that we assign to local variables in explicit functions. Our revised script becomes:
       (0 : 0) (1!:2) < scriptdir, 'ex2.ijs'
    w   =. 1 + 1
    foo =: + & w
    )
Secondly, we need something for `w` to be local to, that is, an explicit function, because outside any explicit function (that is, "at the top level") `=.` is the same as `=:` All that would be needed is the merest wrapper of explicit definition around `0!:n`, such as:
       LL =: 3 : '0!:0 y.'
If we now load our script
       LL < scriptdir, 'ex2.ijs'
and then look at the results:
`foo` | `w`
    +&2
    error
we see that `foo` is as expected, and, as intended, there is no value for `w`. Therefore `w` was local to the execution of the script, or strictly speaking, local to the execution of `LL`. An advantage of the `load` verb is that it provides the explicit function needed to make `w` local.
       erase 'foo';'w'
    1 1

       load scriptdir, 'ex2.ijs'
`foo` | `w`
    +&2
    error
### 26.5.1 Local Verbs in Scripts In the previous example, the local variable `w` was a noun. With a local verb, there is a further consideration. Here is an example of a script which tries to use a local verb (`sum`) to assist the definition of a global verb (`mean`).
       (0 : 0) (1!:2) < scriptdir, 'ex3.ijs'
    sum  =. +/
    mean =: sum % #
    )

       load  < scriptdir, 'ex3.ijs'
We see that this will not work, because mean needs `sum` and `sum`, being local, is no longer available.
`mean` | `sum`
    sum % #
    error
The remedy is to "fix" the definition of `mean`, with the adverb `f.` (as we did in Chapter 12). Our revised script becomes
       (0 : 0) (1!:2) < scriptdir, 'ex4.ijs'
    sum =. +/
    mean =: (sum % #)  f.
    )
Now `mean` is independent of `sum`
       load  < scriptdir, 'ex4.ijs'
`mean` | `sum`
    +/ % #
    error
## 26.6 Loading Into Locales We looked at locales in Chapter 24. When we load a script with `0!:n` or `load` it is the current locale that becomes populated with definitions from the script. By default, the current locale is `base`. In general, we may wish to load a script into a specified locale, say locale `one`. There are several ways to do this. Evidently we can switch to locale `one`, load, and switch back to the `base` locale.
       18!:4 < 'one'
       load  scriptdir,'example.ijs'
       18!:4 < 'base'

       plus_one_
    +
Another way is to specify a locale, `two` say, like this:
       load_two_  scriptdir, 'example.ijs'

       plus_two_
    +
Yet another way is to let the script itself specify the locale. For example,
       (0 : 0) (1!:2) < scriptdir, 'ex5.ijs'
    18!:4 < 'three'
    w   =. 1 + 1
    foo =: + & w
    )
and then the script steers itself into locale `three`
       load scriptdir, 'ex5.ijs'

       foo_three_
    +&2
Here is a further advantage of `load` compared with `0!:n`. Notice that the current locale is `base`.
       18!:5 ''  NB. current locale before loading
    +----+
    |base|
    +----+
If we now `load` `ex5.ijs`, the currentlocale is still `base` afterwards, regardless of the fact that the script visited locale `three`.
       load scriptdir,'ex5.ijs'
       18!:5 ''  NB. current locale after loading
    +----+
    |base|
    +----+
However, loading the same script with `0!:n` does NOT restore the previously current locale.
       18!:5 '' NB. current locale before loading
    +----+
    |base|
    +----+
       0!:0 < scriptdir,'ex5.ijs'
       18!:5 '' NB.  current locale after loading
    +-----+
    |three|
    +-----+
so we conclude that self-steering scripts should be loaded with `load` and not with `0!:n`. ## 26.7 Repeated Loading, and How to Avoid It Another advantage of `load` is this. Suppose one script depends on (definitions in) a second script. If the first includes a line such as `load 'second'` then the second is automatically loaded when the first is loaded. If we load the first script again (say, after correcting an error) then the second will be loaded again. This may be unnecessary or undesirable. The predefined verb `require` is like `load` but does not load a script if it is already loaded. Here is a demonstration. Suppose we have these two lines for the first script:
       (0 : 0) (1!:2) < scriptdir,'first.ijs'
        require scriptdir, 'second.ijs'
        a =: a + 1
    )
Here the variable `a` is a counter: every time `first.ijs` is loaded, `a` will be incremented. Similarly for a second script:
       (0 : 0) (1!:2) < scriptdir, 'second.ijs'
        b  =: b + 1
    )
We set the counters `a` and `b` to zero, load the first script and inspect the counters:
`(a =: 0),(b =: 0)` | `load scriptdir, 'first.ijs'` | `a,b`
    0 0
    1 1
Evidently each script has executed once. If we now load the first again, we see that it has executed again, but the second has not:
`load scriptdir,'first.ijs'` | `a,b`
    2 1
The effect is achieved by automatically tracking what has been loaded with `load` or `loadd` or `require` in a table called `LOADED_j_`. The following shows the last few entries in LOADED_j_
       ,. _4 {. LOADED_j_
    +----------------------------+
    |/home/book/draft9/ex4.ijs   |
    +----------------------------+
    |/home/book/draft9/ex5.ijs   |
    +----------------------------+
    |/home/book/draft9/second.ijs|
    +----------------------------+
    |/home/book/draft9/first.ijs |
    +----------------------------+
## 26.8 Load Status We saw above that the J system maintains a record of which scripts have been loaded with the `load` verb. There is another separate system which keeps track of ALL scripts loaded, whether with `load` or with `0!:0`. The built-in verb `4!:3` with a null argument gives a report as a boxed list of filenames. Here are the last few entries in this report.
       ,. _4 {. 4!:3 ''
    +----------------------------+
    |/home/book/draft9/ex4.ijs   |
    +----------------------------+
    |/home/book/draft9/ex5.ijs   |
    +----------------------------+
    |/home/book/draft9/first.ijs |
    +----------------------------+
    |/home/book/draft9/second.ijs|
    +----------------------------+
Recall that we defined `plus` in the script `example.ijs` which we loaded above. The built-in verb `4!:4` keeps track of which name was loaded from which script. The argument is a name (`plus` for example) and the result is an index into the list of scripts generated by `4!:3`. We see that `plus` was indeed defined by loading the script `example.ijs`
`i =: 4!:4 < 'plus'` | `i { 4!:3 ''`
    12
    +-----------------------------+
    |/home/book/draft9/example.ijs|
    +-----------------------------+
## 26.9 The Profile A J session begins with the automatic behind-the-scenes loading of a script file called the "profile". The contents of the profile can be whatever we choose - whatever function definitions or other things we find convenient to have on hand as our regular setup at the beginning of a session. Commonly a profile itself loads a further selection of library scripts and our own scripts. The profile to be used is specified in the operating-system command-line initiating the J session. If no profile is specified in the command-line, then a standard system-supplied profile is used. In this case a session begins with the automatic execution of:
         0!:0 < installationdirectory , 'system/extras/config/profile.ijs'
Loading this standard profile will load a further standard selection of library scripts, to give a set of commonly useful predefined verbs. The user can customize the standard profile to load further scripts. ### 26.9.1 Summary The recommendation is : Use the standard profile, or the standard profile with additional customizing. This ensures that a session begins having loaded the standard library scripts. Use `load`, `loadd` or `require` for loading scripts. This is the end of Chapter 26.

NEXT
Table of Contents
Index

Copyright © Roger Stokes 2003. This material may be freely reproduced, provided that this copyright notice is also reproduced.

last updated 3 Oct 2003