Guides/Multiple Verb Arguments

From J Wiki
Jump to: navigation, search

Here are some strategies for supporting multiple arguments to a verb.


Ordered List

The simplest way is to make a boxed list of the arguments, and assign them on entry to the verb. For example:

NB. net present values
NB. y has 4 elements:
NB.   imm  =  0=advance, 1=arrears
NB.   frq  =  payment frequency (e.g. 1=annual, 12=monthly)
NB.   int  =  annual earned interest rate
NB.   pay  =  payments per annum
npv=: 3 : 0
'imm frq int pay'=. y
...
)

npv 1;12;0.10 5 0.09;24#1

In most cases, this works fine. Some problems are that:

  • the arguments must be given in order
  • all arguments must be given, even where they are default values
  • the verb needs changing when the argument list changes

Ordered Lists with Trailing Defaults

In some cases, the ordered list can be given in part, with default values supplied for any missing trailing values. This works best when the defaults are empty, for example:

foo=: 3 : 0
'val df knots degree' =. 4 {. boxopen y
...
)

A more complicated example with specified defaults:

foo=: 3 : 0
arg=. boxopen y
'val df knots degree' =. arg, (#arg) }. 0 ; 0 ; '' ; 5
...
)

Name/Value Pairs

Arguments may be given in name/value pairs, and the names assigned within the verb. With this method, it is simplest to define all default values first, then define all name/value pairs. Convenient forms for the name/value pairs are:

  • a list that alternates names and values
  • a 2-column table of names;values.

A verb can support one or both such forms. For example:

NB. version of npv with imm and frq set to defaults
NB. y is a list of name/value pairs or a table of same
npv=: 3 : 0
imm=. 0
frq=. 12
arg=. _2[\,y
({."1 arg)=. {:"1 arg
...
)

npv 'pay';(24#1);'int';0.10 5 0.09

Utility Script

The process of naming and defaulting verb parameters can be automated. This example uses the verb parameterization script:

load '~user\parameterized_verbs.ijs'

parameterizedVerb   =:  verb defn
        filename    =  'c:\short.log'
        max         =  42
        color       =  'red'
)
	
        smoutput  LF,'======='

        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  '======='
)

Note the use of defn instead of define. The verb's formal parameters are named and defaulted in a preamble to the verb definition, effectively adding syntax to J. Here's an example of how the verb could be used:

   parameterizedVerb _2 ]\ 'filename';'c:\long.log';  'max';100;  'color';'blue'
=======
Logging to:  c:\long.log
Max is:  100
Your favorite color is blue
=======
}}}  For futher examples, see the message where the [wiki:JForum:programming/2008-August/011866 script was presented].

If this script doesn't suit your needs, you can roll your own. Note that 2-column tables are supported by the pack and map scripts. Pack supports simple 2-column tables of names and values; map supports nested tables of key;value pairs, where the keys need not be proper names, and may be nested.

For example:

load 'pack'
pay=. 24#1
int=. 0.10 5 0.09
npv pack 'pay int'

Globals

Another alternative is to define values as globals. Note that with the use of locales, such globals are really local to the locale, and should not conflict with other global variables.

As Raul Miller points out in a forum message: "one other thing to keep in mind is that J's locales work rather well as name value collections. The downside is that you reference locales -- they are not values in and of themselves."



This note was prompted by forum thread JForum:programming/2008-August/011863 . See the thread for other methods.

Contributed by Chris Burke