User:Andrew Nikitin/loadlit

From J Wiki
Jump to navigation Jump to search

Use scenarios for jtangle.ijs

Support for literate programming in J is provided by Literate/Wiki Tool.

In offline mode User:Andrew Nikitin/Jtangle script provides facilities for code extraction from literate MoinMoin pages.

jtangle.pl is a standalone command line utility that can be used for maintenance.

jtangle.ijs implements similar functionality in J.

Performing extra step of extracting code portion from literate source before execution may be just enough bother to discourage its use altogether.

This article describes several alternative of how jtangle.ijs verbs can be seamlessly (more or less) integrated into development routine.

jadeful hack, direct

One of the alternatives is a hack which replaces the standard load utility in system\extras\util\jadefull.ijs and/or system\extras\util\jadecon.ijs to perform source extraction step automatically if needed.

load_z_=: 3 : 0
0 load y
:
fls=. getscripts_j_ y
fn=. ('script',x#'d')~
for_fl. fls do.
  if. DISPLAYLOAD_j_ do. smoutput > fl end.
  if. '.lit' -: _4 {. > fl do.
    NB. special treatment for .lit files
    NB. modify location of jtangle.ijs if different
    require '~nsg/literate/jtangle.ijs'
    0!:(100+x) readlit_jtangle_ fl
  else.
    fn fl
  end.
  LOADED_j_=: ~. LOADED_j_,fl
end.
empty''
)

With this hack load will treat files with extension .lit specially. It will extract j program from literate page and run it, ignoring all the literate comments. This way developers edits .lit file, saves it and runs it with load. There is no need in extra code extraction step.

jadeful hack, indirect

Alternatively, execute at startup

(3 : 0) (0 : 0)
  NB. --- begin hack ---
  if. '.lit' -: _4 {. > fl do.
    require '~nsg/literate/jtangle.ijs'
    0!:(100+x) readlit_jtangle_ fl
  else.
    fn fl
  end.
  NB. --- end hack ---
)
  loadsrc=.5!:5 <'load_z_'
  lines=.}.<;.2 }:loadsrc
  NB. skip hack if jtangle is mentioned anywhere in the body
  if. +./ ([: +./ 'jtangle.ijs'&E.)&> lines do. return. end.
  is=.I. ([: +./ 'fn fl'&E.)&> lines
  if. 1~:#is do.
    smoutput 'cannot enable .lit'
  else.
    load_z_=:3 : (;(<y) ({.is)} lines)
  end.
  empty ''
)

This has the advantage of mild futureproofing, since it replaces only part of the load_z_ and only if load_z_ does not have jtangle already.

Stub .ijs

Suppose, developer has a library of verbs in mylib.lit file. He has another script workscript.lit that uses this library. He can write

require 'mylib.lit'

in the workscript.lit and with the jadeful hack described above it should work perfectly.

However, when both scripts are tangled for deployment on the system that does not have or want literate facilities these references are not valid.

Developer can create stub .ijs files:

NB. mylib.ijs
require 'jtangle.ijs'
0!:100 readlit_jtangle_ 'mylib.lit'

and

NB. workscript.ijs
require 'jtangle.ijs'
0!:100 readlit_jtangle_ 'workscript.lit'

Reference to mylib in workscript.lit looks like require 'mylib.ijs' -- the same way it looks on a target system without jtangle, except that on that target system stubs are replaced with tangled code.

As an added bonus this approach allows to select one of several files defined in .lit as developer's source:

NB. mylib.ijs
require 'jtangle.ijs'
0!:100 'mylib-with-debug.ijs' readlit_jtangle_ 'mylib.lit'

I am open for suggestions on how to implement/organize things better. -- Andrew Nikitin <<DateTime(2010-05-27T16:14:34-0400)>>