User:Dan Bron/Temp/LexicalClosure

From J Wiki
Jump to navigation Jump to search

Lexical Closure in J

STOP

If you want to know how to solve Paul Graham's accumulator generator challenge, then you are looking for the FAQ on that topic .

If, however:

  1. you've read that page and
  2. you're familiar with J and
  3. you want a chuckle

then you've come to the right place. Read on.

motivation

This page has the same motivation as the FAQ on lexical closure, but answers it in a (abusively) different way.

solution

Read the caveats. Then download the lexical closure script. Save it at jpath '~addons\lexicalclosure.ijs'. Then:

   load '~addons\lexicalclosure.ijs'

   accGen=. 4 : 'x =. x + y'  lexicalClosureOnRHA
	
   acc0 =. 0 accGen
   acc0 1
1
   acc0 1
2
	
   acc10 =. 10 accGen  NB.  Start with 10
   acc10 78.5
88.5
	
   100 accGen"0 i. 10  NB.  Anonymous accumulator
100 101 103 106 110 115 121 128 136 145

generalization

In order to provide some redeeming value with this page, I present a generalization.

In combination with a the parameterized verb script I previously presented, we can have named local arguments whose values are preserved .

Using the following definition of the verb parameterizedVerb :

        NB.  Define a parameterized verb.  A noun-define is used to create the default parameter table,
        NB.  to enhance readability.
        parameterizedVerb   =:  (verb define) defineAndDefaultParams (makeParamTable noun define)
                filename    = 'c:\short.log'
                max         = 42
                color       = 'red'
                increment*  = 0  NB.  This is flagged, so its state is preserved across calls.
)
                smoutput LF,'======='
                smoutput 'This is ordinal call #',":increment =. >: increment

                smoutput 'Logging to:  ', filename
                smoutput 'Max is:  '  , ": max

                if. color_is_default do.
                        smoutput 'My favorite color is ',color
                else.
                        smoutput 'Your favorite color is ',color
                end.

                smoutput '======='
)

The the following sentences result in the corresponding outputs:

   NB.  Use all the defaults
   parameterizedVerb ''
=======
This is ordinal call #1
Logging to:  c:\short.log
Max is:  42
My favorite color is red
=======

   NB.  Change the first parameter (filename).
   parameterizedVerb '\\server\share\app_logs\myapp.log'
=======
This is ordinal call #2
Logging to:  \\server\share\app_logs\myapp.log
Max is:  42
My favorite color is red
=======

   NB.  Change the first two parameters (filename & max)
   parameterizedVerb '\\server\share\app_logs\myapp.log';906
=======
This is ordinal call #3
Logging to:  \\server\share\app_logs\myapp.log
Max is:  906
My favorite color is red
=======

   NB.  Change the specified parameter (color)
   parameterizedVerb _2 ]\ ;: 'color blue'
=======
This is ordinal call #4
Logging to:  c:\short.log
Max is:  42
Your favorite color is blue
=======

   NB.  Ditto - names are normalized before testing for equivalence (see normalizeNames, which can be changed to suit your needs).
   parameterizedVerb _2 ]\ ;: 'COLOR blue'
=======
This is ordinal call #5
Logging to:  c:\short.log
Max is:  42
Your favorite color is blue
=======

   NB.  Supply new default parameter table.
   NB.  This will turn off the closure of x.
   stringToTabl  =.  (0&".`]@.(__&e.@:(__&".))&.>)@:(_2&(]\))@:(<;._1)
   ' filename f:\output.log max 999 color verdigris increment 0'  parameterizedVerb&:stringToTabl ' max 1000'
=======
This is ordinal call #1
Logging to:  f:\output.log
Max is:  10000
My favorite color is verdigris
=======

Caveats

  1. The verbs returned by defineAndDefaultParams are anonymous. You can't use the debug facility with them.
  2. The entire scheme for closure here is predicated upon J mapped files. Hence:
    • Space for J mapped files has to be pre-allocated. Thus if you close names that grow across calls, you'll eventually get an allocation error.
    • This won't work under Linux because I use 'winapi' to get a temporary file name.
    • The mapped files aren't cleaned up automatically. Every time you run defineAndDefaultParams another file will be created (with a size proportional to n.). You'll need to clean these by hand.
  3. This is a cute, but really stupid, way to get closures. I'm abusing JMF. I don't expect you to use this seriously. Just use globals. Redefining defineAndDefaultParams to make this transparent (by storing the default LHA as a global in a special locale) is trivial.