Given a string containing a (valid) verb, how do I obtain that verb without committing it to any variables? For example, say eval is that function; it should work like this:
eval '+ @ >: @ %'
+@>:@%
eval '+'
+
I only need it to be able to execute verbs and return them, but it would be cool to have arbitrary code be eval'd. (I do know about "., BTW.)
As a fun little experiment, I thought "hey, maybe I can make a verb that will transform a string of verbs into a train of verbs!" I know that I can use ;: to "word-ify" the string into J-verbs, like so:
]str =: '+ >: %'
+ >: %
;: str
┌─┬──┬─┐
│+│>:│%│
└─┴──┴─┘
So far, so good. Now, I just will primatively "join" them with '@' by using ,. ("ravel items"):
'@' ,.~ > ;: str
+ @
>:@
% @
Flattening this yields:
+ @>:@% @
And finally, chopping off the trailing @ with }: yields + @>:@%, an uglier version of what I want, + @ >: @ %.
Now, this is all good and well, except for one thing: it's a string. Almost there! But not quite. I thought to myself, "Oh! ". would be perfect for this, it's basically eval." To my dismay, the docs read thus (emph mine):
".yexecutes the sentencey. If the execution results in a noun, the result of".yis that noun; if the execution result is a verb, adverb, or conjunction, or if there is no execution result, the result of".yis an empty vector.
Well, darnit. That won't work. I can certainly hack it together by defining a verb from within the string:
]verb =: , }: , '@' ,.~ > ;: str
+ @>:@%
'ret =: ' , verb
ret =: + @>:@%
". 'ret =: ' , verb
ret
+@>:@%
And this is all well and good, but rather clumsy, especially for J. The blow can be softened slightly with this is verb:
is =: ".@(,&'=:'@,@[,}:@,@('@',.~>@;:)@])
'G' is '+>:%'
G
+@>:@%
G 5
1.2
But only works if you're willing to commit the function to a variable.
So, my question stands: how do I convert a generic string holding a verb into a usable verb?
Evoke gerund (`:) is what you want. Please refer to this short documentation for good examples. And in your case:
str=: '+ @ >: @ %'
(;: str) `:6
+@>:@%
You may want to review Tie (`) to understand this. ;: returns gerunds in our case (atomic representations), and m `: 6 converts gerund m to verb train.
Alternatively
str =: '+ >: %'
g =: verb def (str,' y')
g 5
1.2
You can also try monad or dyad if you wish, e.g.
2 (dyad def 'x * + % y') 5
0.4
Or to make a train, wrap str in parenthesis:
2 (dyad def 'x (* + %) y') 5
10.4
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With