NYCJUG/2005-10-11

From J Wiki
Jump to: navigation, search

Meeting organization, use J wiki for website, software design - lessons from Unix philosophy, learning materials, what application packages should J have,

Meeting Agenda for NYC JUG 20051011

1. How shall we organize future meetings?  Do we want to set aside time
   for more individually-driven concerns?  For book or article reviews?
   What would be the organizational implications of this?


2. Starting a website: what goes on it?  Who can do what?  How shall
   we host it?  Can we use J on it?


3. Learning materials: establish some categories.

   A. Propaganda materials: see Mario Sacco's e-mail "whyAPLSaccoLetter.txt".

   B. "Alignment" materials: how can we re-frame the speed-of-execution
      discussion to become a total-time-to-solution discussion?  See
      "randTestTiming.txt".


4. What application packages would be helpful for J to have (e.g.
   quadratic solver)?


5. Idea for maintenance & debugging: how can we include sample
   data in (maybe) comments in code?  E.G. I was debugging some
   code and wasn't sure how a result from a sub-function should look.
   Fortunately, I was able to grep old session logs to find an earlier
   debug session to see that a mat needed to be transposed.
   [see sampleDebugArrayExampleUse.txt]

How to Organize Future Meetings

We talked about organizing our meetings differently in the future.

In order to set aside time for more individually-driven concerns, we plan to segment the meeting according to the following topics:

  • Beginners - present summations of basic books and articles (like Chris Burke's comparison of APL and J) with an eye to providing a guide to the strengths and weaknesses of the various introductory materials, getting explanations from more advanced J users, and highlighting beginners' insights and perspectives on learning the language.
  • Show and Tell - presentations of small pieces of codes that a member finds fun or interesting or puzzling; discuss alternate ways to do things and their pros and cons.
  • Group Project - much like what we've been doing previously: discuss progress and insights about the nature of the problem, examine code.
  • Advanced Topics - talk about some of the deeper and more abstract language issues (such as tacit versus explicit definition or how "parts of speech" combine) and some of more obscure, less used, or recently noticed features of the language or provided packages.
  • Q&A - general questions people would like to present to the group. This is less of a discrete segment than an ongoing part of each of the preceding segments but may provide a forum for miscellaneous topics not addressed therein.

The Philosophy of Unix and Fear of Features

I distributed some writings (see "the Philosophy of UNIX.doc" and the more extensive "Basics of the Unix Philosophy_ch01s06.html") on the philosophy of Unix because it has a lot in common with the philosophy behind J and it encapsulates some good, general rules for software design.

A few particularly relevant points are: "small is beautiful", "choose portability over efficiency" (our own interpretation prefers correctness over speed - see the "re-framing discussion" below), and "use software leverage to your advantage". On this last point, the proliferation of GUI-only interfaces has de-leveraged the software advantage by forcing many tasks to be manual and not automatable.

Jim brought up the point that the richness of a language like APL can make people afraid because it can seem so overwhelming and unfamiliar. This suggests the virtue of a layered approach to presenting such languages: we need to present simpler more familiar things, like scalar addition, then simple extensions, like other scalar math functions, before layering on the unfamiliar parts like multi-dimensional arrays: going from scalars to vectors, then matrixes, and so on.

We also talked about our own frustration with the J form designer and how we need to get together a body of well-documented and indexed examples. Some of this difficulty may stem from being used to a functional approach and having to learn a new way of thinking necessary for an event-driven framework. I mentioned the forms editor package (which has a lab to explain it) but no one seemed to like using this though it's not clear why. Do people prefer a more cluttered interface like the form designer in Visual Basic? Do we concentrate too much on the guts of algorithm design and too little on the user interface to have sufficient experience with using forms?

Tenets of Unix

There are some good ideas behind Unix that we should borrow freely. For instance here's some basic tenets of software design that may resonate with the J community.

The Unix Philosophy The Nine Major Tenets

1. small is beautiful 2. make each program do one thing well 3. build a prototype as soon as possible 4. choose portability over efficiency 5. store numerical data in flat files 6. use software leverage to your advantage 7. use shell scripts to increase leverage and portability 8. avoid captive user interfaces 9. make every program a filter

Ten Lesser Tenets

1. allow the user to tailor the environment 2. make operating system kernels small and lightweight 3. use lower case and keep it short 4. save trees 5. silence is golden 6. think parallel 7. the sum of the parts if greater than the whole 8. look for the ninety percent solution 9. worse is better 10. think hierarchically

These are from the books The Unix Philosophy by Mike Gancarz and Linux and the Unix Philosophy by Mike Gancarz and Jon "Maddog" Hall.

some sites that go into detail on this topic:

David Korn speaks out:

FROM: http://hebb.cis.uoguelph.ca/~dave/27320/new/unixphil.html

The UNIX Philosophy From The UNIX Philosophy by Mike Gancarz. Operating systems embody the philosophy of their creators.

  • Mac/OS is visually based with all options presented to the user
  • DOS attempts to create a taste of the mainframe
  • DEC VMS assumes users fear the machine and should be given a

few powerful choices

The creators of Unix assumed that its users would be computer literate. Little effort was placed into making it accessible to novices. If you can't understand it, then you don't belong here.

Learning Materials on a Website -> J Wiki

In this meeting we changed direction completely from a couple of meetings ago when everyone seemed interested in putting up our own NYCJUG website: now that the J Software Wiki is available, it seems like a much more attractive option to work on that. (For those who are unfamiliar with the concept of a Wiki, it's a collection of web pages that allows anyone to edit them - see the Wikipedia for the prime example of this.)

This leads us to the question of what exactly we should put on the Wiki. Since we've long had a commitment in the group to learning materials, we need to establish some categories to organize these. One category, not to put too fine a point on it, is simply "propaganda" - pure advocacy of APLs (in the wide sense of array languages). As an example of a flawed attempt at this, I referred to Mario Sacco's e-mail in which he publicized some pertinent criticism of an early attempt to compare APL favorably to Basic (see "whyAPLSaccoLetter.txt"). Mario is the new president of the ACM SIGAPL; this letter requests help in better presenting the case for array languages.

On a related issue is what I call the "re-framing discussion": how can we re-frame the wrong-headed speed-of-execution discussion (where we will always lose the race) to become a total-time-to-solution discussion (where we have the distinct advantage)? See "randTestTiming.txt" for a recent attempt of mine to do this.

Future projects: Application Packages for J?

We get questions on the J Forum like "Does J have a quadratic solver?" It would be nice to answer more of these with something like "Yes, take a look at...."

Miscellaneous Jumbled Rush of Odds and Ends

To finish off this report as quickly as possible, I'll simply list some brief notes on other topics we covered:

  • Instead of copying the Visual Basic forms designer, would our time be better spent simply using that package and translating the ASCII files it generates to build J forms?
  • How can we integrate development with code control with a database of test cases and example usage?
  • Publicize nascent coding and commenting standards, e.g. including specially tagged comments like "NB.* [function name]: [single line description]" and final "NB.EG [example use of function]"? (A good standard requires minimal work for the most benefit.)
  • Develop explicit examples of how Object-Orientated programming maps to use of namespaces?
  • We'd like to have 100 megabytes of examples with 10 paths to reach each example.

Letter from Mario Sacco About Promoting APL(s)

From: Mario Sacco <mario.sacco@tin.it>	Mailed-By: listserv.acm.org
Reply-To: Mario Sacco <mario.sacco@tin.it>
To: SIGAPL-MEMBERS@listserv.acm.org
Date: Sep 29, 2005 2:03 PM
Subject: FW: why APL?
Reply | Reply to all | Forward | Print | Add sender to Contacts list | Trash this message | Report phishing | Show original | Message text garbled?
Hi all,
attached a mail receive some days ago about our "whyapl" page.

Personally I agree with Jim. I'm sure of the superiority (in general) of
APLs over other programming languages regarding array treatment, but I
think is not our mission to demonstrate this.
Our mission has to be, instead, to diffuse an APL culture and make
possible for more people to approach and use this technology.
Attaching other programming languages should only set us in a loser
position, so ... I think this page needs to be urgently *updated*

... any idea about the concepts to include in this "first contact" with
SIGAPL ad Array Programming Languages ?

... what about the use of this introductory page to show code samples of
the different APL dialects (including, at least, J and K) ?

... what about avoid programming language comparison, substituting these
with, simply, a strong computational algorithm and its APL translation
(in all dialects)?

... any volunteer?  :-)

Mario


|-----Original Message-----
|From: Jim Battle [mailto:frustum@pacbell.net]
|Sent: domenica 25 settembre 2005 5.50
|To: infodir_sigapl@acm.org
|Subject: why APL?
|
|Your web page arguing the case for why APL is a superior language:
|
|       http://www.sigapl.org/whyapl.htm
|
|has a number of errors in the BASIC code equivalent of the apl sort function.
|The section begins with the header "How Does APL Compare with other Languages".
...

Example of Debugging and How Arrays Help with this

                sampleDebugArrayExampleUse.txt
                ------------------------------

NB. This was blowing up:
   'rc dt cf'=. combine4CashFiles src
|index error: combine4CashFiles
|   utit=.(TOTLNOut)    (utit i.TOTLNIn)}utit

      col0
+----+----------+--------++----------------+---------------+-----------------+-----------------+---------------+----------------------+------------------+
|DATE|FUNDNUMBER|FUNDNAME||BEGINNINGBALANCE|CONSENTPAYMENTS|FUNDSUBSCRIPTIONS|TOTALCASHRECEIPTS|FUNDREDEMPTIONS|TOTALCASHDISBURSEMENTS|TOTALENDINGBALANCE|
+----+----------+--------++----------------+---------------+-----------------+-----------------+---------------+----------------------+------------------+
      idstr
+------------------+--------+----------+----+
|TOTALENDINGBALANCE|FUNDNAME|FUNDNUMBER|DATE|
+------------------+--------+----------+----+
      idstr e. col0
1 1 1 1
      utit
+----+----+---------+
|Fund|DATE|9/27/2005|
+----+----+---------+
      TOTLNIn
+------------------+
|TOTALENDINGBALANCE|
+------------------+
      TOTLNIn
+------------------+
|TOTALENDINGBALANCE|
+------------------+
      TOTLNOut
+-----+
|TOTAL|
+-----+
      $&.>aa
+-+-+-+-+
|2|2|2|2|
+-+-+-+-+
      $ac
4
      $&.>ac
+---+---+---+---+
|3 8|3 8|3 8|3 8|
+---+---+---+---+
      0{ac
+---------------------------------------------------------------------------------------------------------------------------------------------+
|+---------+----------------+-----------------+----------------+-----------------+-----------------+----------------------+------------------+|
||Fund     |CON (fund 56580)|                 |                |                 |                 |                      |                  ||
|+---------+----------------+-----------------+----------------+-----------------+-----------------+----------------------+------------------+|
||DATE     |FUNDNUMBER      |FUNDNAME         |BEGINNINGBALANCE|FUNDSUBSCRIPTIONS|TOTALCASHRECEIPTS|TOTALCASHDISBURSEMENTS|TOTALENDINGBALANCE||
|+---------+----------------+-----------------+----------------+-----------------+-----------------+----------------------+------------------+|
||9/27/2005|56580           |MS Con Allocation| -              | 277360.08       | 277360.08       | 12099.62             | 265260.46        ||
|+---------+----------------+-----------------+----------------+-----------------+-----------------+----------------------+------------------+|
+---------------------------------------------------------------------------------------------------------------------------------------------+
      atit
+---------------------+---------------------+---------------------+---------------------+
|+----+----+---------+|+----+----+---------+|+----+----+---------+|+----+----+---------+|
||Fund|DATE|9/27/2005|||Fund|DATE|9/27/2005|||Fund|DATE|9/27/2005|||Fund|DATE|9/27/2005||
|+----+----+---------+|+----+----+---------+|+----+----+---------+|+----+----+---------+|
+---------------------+---------------------+---------------------+---------------------+

            +.--------------------+.

From the command line:

[Tue 09/27/2005 | 16:16:34.28 | C:\amisc\Jsys\temp]
>grep -i extractdailycash *.ij?
45.ijx:|   ac=.extractDailyCash&.>    (<td),&.>fls
46.ijx:| | |       ac=. extractDailyCash&.> (<src),&.>fls                                 |
46.ijx:    ac=. extractDailyCash '\global\FoF\History\20050504\'
46.ijx:    ac=. extractDailyCash '\global\FoF\History\20050504\267004 cash.xls'
46.ijx:   extractDailyCash
46.ijx:|3|:|NB.* extractDailyCash: extract sub/redemp info from daily cash spreadsheet.                             |
46.ijx:| | |NB.EG extractDailyCash '\global\FoF\History\20050405\267009 cash.xls'                                   |
46.ijx:    ac=. extractDailyCash '\global\FoF\History\20050504\267004 cash.xls'
46.ijx:   ac=. extractDailyCash&.> (<src),&.>fls
46.ijx:   ac=. extractDailyCash&.> (<src),&.>fls
46.ijx:   ac=. extractDailyCash&.> (<src),&.>fls
52.ijx:   ac=. extractDailyCash&.> (<src),&.>fls
53.ijx:      aa=. extractDailyCash '\AAF\History\20050713\267001 cash.xls'
53.ijx:      aa=. extractDailyCash '\AAF\History\20050713\267001 cash.xls'
53.ijx:   13!:3 'extractDailyCash 4 5 6 7'
53.ijx:   aa=. extractDailyCash '\AAF\History\20050713\267001 cash.xls'
56.ijx:|index error: extractDailyCash
56.ijx:      13!:3 'extractDailyCash 15 16 17'
56.ijx:|extractDailyCash[15]
56.ijx:      13!:3 'extractDailyCash'
56.ijx:| | |       aa=. extractDailyCash&.> (<src),&.>fls                                  |
58.ijx:extractCompletedTrades  extractDailyCash        extractFIFromXLS
. . .
createdir.ijx:      13!:3 'extractDailyCash'
createdir.ijx:| | |       aa=. extractDailyCash&.> (<src),&.>fls                                  |
trades050713-18.ijx:|index error: extractDailyCash

[Tue 09/27/2005 | 16:16:45.89 | C:\amisc\Jsys\temp]
>

            +.--------------------+.

NB. Looking into an early debug session in 53.ijx:

   updateAndShowCFs (gof,'History\20050713\');rpts,'AAFSubsReds.xls'
|assertion failure: combine4CashFiles
|   1=#dt=.~.a:-.~{.&>aa
   updateAndShowCFs (gof,'History\20050713\');rpts,'AAFSubsReds.xls'
      1{"1 rmEmptyCols dat{~col0 i. IDSTR
+---------+-------------------------------------+------+---------+
|7/13/2005|MAINSTAY CONSERVATIVE ALLOCATION FUND|267001|7/12/2005|
+---------+-------------------------------------+------+---------+
      dt
7/12/2005
      hdr
+----+--------------------------+
|Fund|CONSERVATIVE (fund 267001)|
+----+--------------------------+
      titnum
+------------------------+---------+
|CLOSINGBALANCE          |0.00     |
+------------------------+---------+
|SUBSCRIPTION/REDEMPTIONS|127689.17|
+------------------------+---------+
|TOTAL                   |127689.17|
+------------------------+---------+
|TODAY'SDATE             |         |
+------------------------+---------+
NB. and
      >aa
+---------+--------------------------------------------------------+
|7/12/2005|+------------------------+--------------------------+   |
|         ||Fund                    |CONSERVATIVE (fund 267001)|   |
|         |+------------------------+--------------------------+   |
|         ||CLOSINGBALANCE          |0.00                      |   |
|         |+------------------------+--------------------------+   |
|         ||SUBSCRIPTION/REDEMPTIONS|127689.17                 |   |
|         |+------------------------+--------------------------+   |
|         ||TOTAL                   |127689.17                 |   |
|         |+------------------------+--------------------------+   |
+---------+--------------------------------------------------------+
. . .

NB. I can see the improperly formed array.

            +.--------------------+.

NB. After transposing a sub-array to be as expected:

   load '\aaf\fof.ijs'
   'rc dt cf'=. combine4CashFiles src
   rc
1
   dt
9/27/2005
   cf
+---------+----------------------+-----------------+----------------------+-----------------------------+--------------------+
|Totals   |Fund                  |CON (fund 56580) |MODERATE (fund 56750) |MODERATE GROWTH (fund 56760) |GROWTH (fund 56650) |
+---------+----------------------+-----------------+----------------------+-----------------------------+--------------------+
|         |DATE                  |9/27/2005        |9/27/2005             |9/27/2005                    |9/27/2005           |
+---------+----------------------+-----------------+----------------------+-----------------------------+--------------------+
|226740   |FUNDNUMBER            |56580            |56750                 |56760                        |56650               |
+---------+----------------------+-----------------+----------------------+-----------------------------+--------------------+
|         |FUNDNAME              |MS Con Allocation|MS Moderate Allocation|MS Moderate Growth Allocation|MS Growth Allocation|
+---------+----------------------+-----------------+----------------------+-----------------------------+--------------------+
|         |BEGINNINGBALANCE      | -               | -                    | -                           | -                  |
+---------+----------------------+-----------------+----------------------+-----------------------------+--------------------+
|979203.77|FUNDSUBSCRIPTIONS     | 277360.08       | 487551.78            | 95521.49                    | 118770.42          |
+---------+----------------------+-----------------+----------------------+-----------------------------+--------------------+
|979203.77|TOTALCASHRECEIPTS     | 277360.08       | 487551.78            | 95521.49                    | 118770.42          |
+---------+----------------------+-----------------+----------------------+-----------------------------+--------------------+
|29931.34 |TOTALCASHDISBURSEMENTS| 12099.62        | 7686.76              | 9287.72                     | 857.24             |
+---------+----------------------+-----------------+----------------------+-----------------------------+--------------------+
|949272.43|TOTAL                 | 265260.46       | 479865.02            | 86233.77                    | 117913.18          |
+---------+----------------------+-----------------+----------------------+-----------------------------+--------------------+

Re-framing the Speed-of-Execution Discussion

                    randTestTiming.txt
                    ------------------
From: Erling Hellenas <erling.hellenas@runbox.com>	
Reply-To: J Forum <JFORUM@peach.ease.lsoft.com>
To: JFORUM@peach.ease.lsoft.com
Date: Sep 29, 2005 8:28 PM
Subject: [Jforum] Random. Was Shootout..
Reply | Reply to all | Forward | Print | Add sender to Contacts list | Trash this message | Report phishing | Show original | Message text garbled?

Hi all !

Made an uncomplete shot at the "random" benchmark at the shootout site.
http://shootout.alioth.debian.org/

Took 22 seconds against 0.07 for the C program. What can I say ? Earlier
with APL you could often beat assembler and C programs with an efficient
APL algorithm if you could avoid all looping constructs and work on arrays.
With looping constructs it was always hopelessly slow because of a lot of
interpretation and no calculation. I guess with J it seems to be about the
same. I thought this was the most obvious way to write this program.
According to the rules it should be written in the same way as the C
program.

Seems hopeless, but maybe we can make an efficient version ?

Actually I started with a version that first generated the seeds, then the
random numbers, all on arrays. Since you can hardly work of 900 000 long
arrays though, you would need another loop, say 90 times 10000 or
something. Would look rather strange, wouldn't it ? To allocate an 8 MB
array would look strange too, wouldn't it ? Even if it is a big test
machine I mean.

Well, I guess there is at least some way to write a tacit version.

Cheers,

Erling Hellenäs

--------Code-------------------
NB. See http://shootout.alioth.debian.org/
ts=: 6!:2 , 7!:2@]       NB. Time and space
IM=:139968
IA=:3877
IC=:29573
last=:42
gen_random=: 3 : 0
last=:IM |(last *IA)+IC
y. *last % IM
)
loop=: 3 : 0
k=. y.
while. k=.<:k do.
gen_random 100
end.
gen_random 100
)
loop 900000
ts''
ts'loop 900000'

NB. random C gcc program
NB. N  Full CPU Time s Memory Use KB CPU Time s Code Lines
NB. 900,000 0.07 268 0.07 16

NB. random J program
NB. N  Full CPU Time s Memory Use KB CPU Time s Code Lines
NB. 900,000  21.90 3520 21.90 15

------Output-----------------
  loop 900000
75.5444
  ts''
3.45214e_6 320
  ts'loop 900000'
21.0937 3456

            +.--------------------+.

From: Devon McCormick <devonmcc@gmail.com>	Mailed-By: gmail.com
Reply-To: devon@acm.org
To: J Forum <JFORUM@peach.ease.lsoft.com>
Date: Sep 30, 2005 4:51 PM
Subject: Re: [Jforum] Random. Was Shootout..
Reply | Reply to all | Forward | Print | Add sender to Contacts list | Trash this message | Report phishing | Show original | Message text garbled?

The start of this thread perpetuates a framework for comparison that will usually
show interpreted languages at a disadvantage and ignores their substantial advantages.
Computer "bit-heads" seem to have always obsessed with squeezing microseconds of
performance out of simple routines even if they spend hours and days doing it.

As someone once said: A week's worth of programming can save you an hour of thought.

I don't know about the rest of you, but the ratio of time I spend coding to the time
I spend running my code is certainly greater than 1,000 to 1.  I would happily use tools
that take ten times as long to run if they also required 1/10 of my time to set up the
problems I'm solving.

The algorithm Erling is working on is a good example of this: it's a simple linear, congruential
random number generator.  In fact, the variable names make it look as though it came straight out
of the Numerical Recipes book (Press, Teukolsky, Vetterling, Flannery).

This is a good example of the problem of benchmarking simple routines because it ignores
the source of the real difficulty: choosing a good routine in the first place.  As has been commented
in this and another thread on this forum, the advantage of a powerful, flexible language like J is
the ability it gives us to work on creatively solving problems.

Furthermore, we already know there are better random number generators than linear congruential ones.
I believe Roger has implemented a Mersenne Twister for J.  Even so, if you read Numerical Recipes, the
difficulty with this type of generator is choosing good values for IA, IC, and IM.  A more interesting
problem would be to explore how to tell if the values chosen in this example are good ones.  In fact,
it's easy to prove they are not.

Consider the following restatement and extension of Erling's original code:

IM=: 139968
IA=: 3877
IC=: 29573
SEED=: 42

lcrandom=: 3 : 0
NB.* lcrandom: linear congruential random number generator.
   y.*IM%~SEED=: IM|IC+SEED*IA
)

looplcr=: 3 : 0
NB.* looplcr: apply lcrandom repeatedly but only look at final result.
   while. y.=.<:y. do.
       lcrandom 100
   end.
   lcrandom 100
)

cumlooplcr=: 3 : 0
NB.* cumlooplcr: apply lcrandom repeatedly, accumulating results.
   rndnums=. (>:y.)$0.0
   while. y.=.<:y. do.
       rndnums=. (lcrandom 100) y.}rndnums
   end.
   rndnums=. (lcrandom 100) 0}rndnums
)

Now, generate 90,000 random numbers and examine them:
   ans=. cumlooplcr 900000
   load 'mystats'
   (mean,stddev,<./,>./) ans
50.000981 28.860757 0 99.999286    NB. These look OK
   load 'plot'
   'point;pensize 2' plot <"1 ] 2 45000$90000{.ans  NB. plot as point-pairs

If you expand this plot to fill up your screen, you should be able to clearly see parallel, slanted
lines.  This indicates this choice of parameters does a poor job of filling up the space randomly.

We can experiment with other parameters:
   'IA IC IM'=: 2^16 8 24     NB. These just have to be bad
   SEED=: 42
   ans=. cumlooplcr 900000
   (mean,stddev,<./,>./) ans
0.0015441064 0.017293696 0 16.407776              NB. Awfully bad
   'point;pensize 2' plot <"1 ] 2 45000$90000{.ans  NB. plot as point-pairs
   ans
0.0015258789 0.0015258789 0.0015258789 0.0015258789 0.0015258789 0.0015258789 0.0015258789 ...
   NB. It's only one point!
   $~.ans
3
   NB. Well, three points.
   ~.ans
0.0015258789 16.407776 0

Pick better values:
   isprime=: 1&=@#@q:
   nextprime=: 3 : '{.y.#~isprime y.=. y.+>:i.100'  NB. Assume there'll be a prime w/in 100
   ]'IA IC IM'=: nextprime&> IA,IC,IM
65537 257 16777259

Try again:
   SEED=:42
   ans=. cumlooplcr 900000
   (mean,stddev,<./,>./) ans
50.001598 28.849836 0 99.99997   NB. OK
   'point;pensize 2' plot <"1 ] 2 45000$90000{.ans  NB. plot as point-pairs

This looks much better.

So, whereas the C programmer can get a poor answer in less than a second, a J programmer
can get a much better answer in a few minutes.  Which do you prefer?

Devon

            +.--------------------+.

  ts=: 6!:2 , 7!:2@]       NB. Time and space
   IM=:139968
   IA=:3877
   IC=:29573
   gen_seed=: IM"_| IC"_+]*IA"_
   gen_random=: [*]%IM"_
   100 gen_random gen_seed 42
37.464992
   gen=: 100"_ gen_random [: |.@}:[:gen_seed/\._900001"_{.]
   ts'gen 42'
3.0106371 20972352

   $ans=. gen 42
900000

   load 'plot'
   'point;pensize 2' plot <"1 ] 2 45000$90000{.ans   NB. Very gappy...

   'point;pensize 2' plot <"1 ] |:45000 2$90000{.ans NB. Not as gappy but regular