Subject: [Jprogramming] Explicit adverbs
"Graham Parkhouse" <[email protected]> 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 <[email protected]>
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm