TL;DR
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):
".y
executes the sentencey
. If the execution results in a noun, the result of".y
is that noun; if the execution result is a verb, adverb, or conjunction, or if there is no execution result, the result of".y
is 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?