Subject: [Jprogramming] Explicit adverbs

"Graham Parkhouse" <graham.parkho...@ntlworld.com> wrote:
> How can I write an adverb that returns a noun from 3 noun arguments x, m and
> y as a *one liner*?
>
> Just 2 arguments is fine:
>   adv1=: 1 : 'm*y'
>   3 adv1 10
> 30
>
> 3 arguments like this doesn't work:
>   adv2=: 1 : 'm*y-x'
>   5 (3) adv2 10
> |domain error
> |   5    (3)adv2 10
>
> Giving it a body works:
>   adv3=: 1 : 0
> :
> m*y-x
> )
>   5 (3) adv3 10
> 15
>
> Is there a way to do it as one liner?

It looks like you are trying to create a triadic function.
If the exact syntax is not important, here are a few other
methods that involve conjunctions:

You can create a conjunction that returns an adverb
   c1 =: 2 : '2 : ''(0{::n)*(1{::n)-m''(m,&>n)'
   5 (3) c1 10
15

This can be simpler, if m and y are of compatible types and shapes:
   c2 =: 2 : '2 : ''({.n)*({:n)-m''(m,:n)'
   5 (3) c2 10
15

Unfortunately, these bind the y parameter tightly so
they can't be used in trains without parenthesizing y;
for example: 5 (3) c1 (5+5) vs. 5 (3) adv1 5+5

It can be simpler to move the middle parameter to the right,
which also avoids the above train issue:
   c3 =: 2 : 'n*y-m'
   5 c3 (3) 10
15

You could make this return a tacit verb:
   c4 =: 2 : 'n&*@(-&m)'
   5 c4 (3) 10
15

Or, to be pedantic (and forbid the dyadic valence):
   c5 =: 2 : 'n&*@(-&m) : [:'
   5 c5 (3) 10
15

You can even do it with a verb, if you externally package the parameters:
   v1 =: {...@]*{:@]-[
   5 v1 3,:10
15

This last method is the only one that is easily extendable
to functions with any numbers of parameters - just box them all
(or concatenate them all, if the types and shapes are compatible),
then cherry-pick the appropriate parameters as required:
   v2 =: 1&{::*2&{::-0&{::
   v2 5;3;10
15

-- Mark D. Niemiec <mniem...@gmail.com>
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to