I'd use an explicit adverb to do: linrep substitute eval assign return assigned value.
I'm not sure if we have a prebuilt routine to substitute a sequence of strings into repeats of the same pattern - if not, that would be the "complex" part of this. Thanks, -- Raul On Thu, Feb 20, 2014 at 4:51 PM, Dan Bron <[email protected]> wrote: > Sorry, I should have clarified the goal is to permit the user to supply the > template as data. So we can do things like: > > '`round digits log'=:(0.5<.@:+])&.:(%&__)`(__&#.^:_1)`(__&^.) substit"0~ > 0.01 10 1x1 > round > (0.5 <.@:+ ])&.:(%&0.01) > digits > 10&#.^:_1 > log > 2.7182818284590451&^. > > > > > ----- Original Message --------------- > > Subject: Re: [Jprogramming] Generating code from templates > From: Raul Miller <[email protected]> > Date: Thu, 20 Feb 2014 15:00:52 -0500 > To: Programming forum <[email protected]> > > This seems really simple, to me. > > Of course, it's hard to tolerate simplicity - it's kind of boring, so we > like to discard features of the language. I think of this urge as a social > artifact of our need for J subset compilers. > > Still, even if we had compilers, it might still make sense to start with a > simple working model before trying to shoehorn our code into a more > constrained set of guidelines. > > Anyways, you just need a verb that, given a number, gives the corresponding > gerund, and use that verb at rank 0. > > In other words: > > constfun=:3 :0"0 > {.y"_`'' > ) > > Testing: > > 100"_`(200"_)`(300"_) -: constfun 100 200 300 > 1 > > More generally, this style of verb has everything you need for "fill in the > blank". You just create a J expression and take the gerund of it (and toss > the unneeded dimensionality). > > I remember arguing with Ken Iverson about this - why have character based > evaluation instead of a more constrained token based evaluation. And I > really struggled to express why we needed anything else. And of course he > did include token based evaluation in the language (`:6) along with parsing > support and a simple, modular parsing model. But for most practical > purposes the character based approach is just simpler to use. (Though of > course: this might change if we started building compilers for language > subsets.) > > Still... simplicity is a virtue. But it's also a bit boring, sometimes. > > Thanks, > > -- > Raul > > > > On Thu, Feb 20, 2014 at 2:39 PM, Dan Bron <[email protected]> wrote: > > > There was a question on StackOverflow today on generating constant > > functions from the items of an array. As in, 100 200 300 <==> > > 100"_`(200"_)`(300"_) . > > > > As a more general question, how can we specify code templates and then > use > > them to dynamically produce gerunds for later execution? * > > > > Here's one idiom I've found useful in such situations: > > > > substit =: [^:(__-:])L:_ 0 > > > > template =: __"_ NB. The template; note the __ > > TEMPLATE =: {. template f.`'' NB. Atomic rep of template > > > > GERUND =: TEMPLATE substit"_1 _~ 100 * 1 + i.3 > > > > GERUND`:6 > > (100"_) (200"_) 300"_ > > > > [email protected] > > 100"_ > > > > [email protected] 'hello' > > 300 > > > > The basic idea is to "fill in the blanks" in the template with the > inputs. > > Here, the blank is __ (negative infinity), so we look for that in the > > gerund template, and when we find it, we replace it with the input. I > kind > > of like how the verb does this: first, we only bother looking at level 0 > > (because __ is unboxed, so it will never appear above level 0), and > > second, the verb is passive until __ is detected (because ^:(]-:__) is > > ^:0, i.e. "do nothing and just return the RHA" until then). > > > > One possible issue is what we use to denote "blank". If we're going to > > allow users to pass in any gerund, then he could potentially want to > > include __ as part of the code to be produced, rather than replaced. > There > > are a couple possible ways to address that limitation. First, we could > use > > a value which a user is very unlikely to want to produce (as opposed to > > replace), i.e. _. : > > > > substit =: [^:(1-:128!:5@])L:_ 0 > > SPARTA =: ({. _."_ `'') substit"_1 _~ 300 > > SPARTA`:6 > > 300"_ > > > > Or, we could define substit as an adverb (adjective), which takes the > > "blank" as an argument: > > > > Substit =: (-:&) (@]) ([^:) (L:_ 0) > > > > substit =: 'blank' Substit > > substit > > [^:(-:&'blank'@])L:_ 0 > > > > ; , ((< {. 'blank'&;`'') substit~&.> ;:'fill in the blanks' )`:0 '!' > > fill!in!the!blanks! > > > > But if we do that, we have to start wondering about the 0 in L:_ 0 , > > because the user's "blank" might be boxed, and therefore have L.>0 . Of > > course, we could fix this up by making the L: dynamic: > > > > Substit =: adverb : '[^:(m-:])L:(_,L.m)' > > > > NOTNULL =: ({. ~:&a:` '') a: Substit~ <'#N/A#' > > NOTNULL`:6 > > ~:&(<'#N/A#') > > > > But it might be more fun to go meta-meta: > > > > (({. substit f.`'') substit~ _999)`:6 > > [^:(_999 -: ])L:_ 0 > > > > Here, define the "standard" blank to be __, and then let the user change > it > > by using substit :) > > > > Anyway, thought I'd share, and see if anyone else has useful tools for > > manipulating J code (metaprogramming). > > > > -Dan > > > > * For a recent example of where such metaprogramming might be useful, or > > convenient, see the postscript of: > > > > > > http://www.jsoftware.com/pipermail/programming/2013-December/034373.html > > > > Other examples can be found with a forum archive search for the string > L:0 > > _ > > ---------------------------------------------------------------------- > > For information about J forums see http://www.jsoftware.com/forums.htm > > > ---------------------------------------------------------------------- > For information about J forums see http://www.jsoftware.com/forums.htm > ---------------------------------------------------------------------- > For information about J forums see http://www.jsoftware.com/forums.htm > ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm
