User:Andrew Nikitin/once

From J Wiki
Jump to navigation Jump to search

once untility

Background

In J session I often need to initialize some noun with values, but only if it does not already have value. For example, a script may contain several verbs for custom data crunching. Some or all of these verbs rely on verious global variables containig the data itself. This data comes originally from files or some formula and may be added to as scripts are executed and interactive data processing session proceeds. As I refine data processing verbs, I need to reload the script to update their definitions. So, if the global initialization statements are written in the body of the script, the data accumulated there will be lost.

Another situation arises when I need to create several numbered locales (objects) to use with verbs in script. For example, I want 2 plots, one for overview one for details. The one for details I am going to update often, so that would be default plot window, from 'jwplot' locale. The one for overview is updated less frequently and I want to keep it open even when "details" plot is open. Si I have to create special locale for it.

If I put

PO=:conew 'jzplot'

in script, and use plot__PO ... any time I need to replot overview this works just fine, except that new numbered locale is created every time I run the script and the old ones just stay unused until J session is closed. So, again, I want to create ne PO locale, but only if there is not alredy one.

Implementation

NB. Perform assignment only if noun is not defined

once=:[: 3 : 0 ;. _2 ,&LF
  'n c'=.2{.;:y
  if. ('=:'-:c) *. (0>4!:0 <n) do.
    smoutput 'Execute ',y
    ".y
  end.
  i.0 0
)

NB. Example

once 'P3=:i.10'

once 0 : 0
    A=:1
    B=:2
    C=:3
)

This straightforward implementation works in most cases, except that it cannot assign a value to globals y, n or c because they are shadowed by local values. That is why we may need

Tacit implementation

once=: [: (smoutput@('Initialize '&,) [ ".)^:((('=:'&-:)@>@{: *. (0>4!:0)@{.)@(2 {. ;:)) ;._2 ,&LF

-- Andrew Nikitin <<DateTime(2010-07-29T10:38:51-0400)>>