That's great. Thank you. For some reason I was expecting the use of an explicit adverb to still be called by name (and thus break the pure, functional, point free concept). My assumption was wrong:
op_cmp =: (([: (([: (*@-~)/ pV&{::) op_push ]) 2 popn)) op_cmp [: (([: *@-~/ 2&({::)) op_push ]) [: ([ ((0 {:: ]) ; (1 {:: ]) ; ((2 {:: ]) , 2 {:: [) ; 3 {:: ]) op_pop)^:2 ] It may not be a surprise to most but I was very happy to see that the result of an adverb on a tacit verb is a new tacit verb Simplified: copy=: (1 : ',^:(<:m) ]') sum4_copies =: [: +/ [: 4 copy ] I would have thought sum4_copies would have been something like [: +/ [: 4 copy ] or [: +/ [: (1 : ',^:(<:m) ]') ] not: [: +/ [: (,^:3 ]) ] If someone has a dictionary or other doc reference handy that explains this I would be grateful to deepen my understanding, although it seems pretty straightforward On Thu, Nov 12, 2015 at 8:44 PM, 'Pascal Jasmin' via Programming <programm...@jsoftware.com> wrote: >>'pC pIP pV pS' =: i. 4 > > > notice that all uses were accessors, so this might have saved some parens. > > > (i.@# 4 : '(y) =: x {:: ] label_. y' each ] ) ;: > 'pC pIP pV pS' > > pC > 0 {:: ] > > > trying to make that a popn > > popn=: 1 : '[: ([ ( (pC{::]) ; (pIP{::]) ; ((pV{::]) , (pV{::[)) ; (pS{::])) > op_pop)^:m ]' > > ...and done. > > > 3 popn > [: ([ ((pC {:: ]) ; (pIP {:: ]) ; ((pV {:: ]) , pV {:: [) ; pS {:: ]) > op_pop)^:3 ] > > ----- Original Message ----- > From: Joe Bogner <joebog...@gmail.com> > To: programm...@jsoftware.com > Cc: > Sent: Thursday, November 12, 2015 8:13 PM > Subject: Re: [Jprogramming] essay: toy byte code interpreter > > Thanks for the feedback. Your utm is impressive and helped me me get > into the style of small bits of tacit composed together and then > fixed. It was a joy to work with at times and frustrating at others. I > think it's worth writing an essay to share tips/tricks for larger > tacit programs. I may take a crack at it. > > Thoughts: > > 1. Tracing execution was somewhat challenging. I finally got the knack > of it with variations of the following: > > (smoutput bind [) ] ]) > > Debug could useful too. I didn't use it as much as I could have when I > was writing this. I have only recently started using debug (really > only twice - to learn more about the internals of plot and the utm). > Need to keep it top of mind for the future and reach for it more often > > 2. Think about the data structure that will be threaded through the > calls up front. I did a reasonable job planning out and using nouns to > describe the various offsets: > > 'pC pIP pV pS' =: i. 4 > > op_push =: (pC {:: ]) ; (pIP {:: ]) ; '' ; (<@: ((0{[) , getStack)) > > This became problematic because I thought I'd be clever at points and > use 2{. to skip and then when I inserted something in the beginning it > broke alot of things. For example, I didn't have pC (the code) as part > of the structure until I implemented jumps, so I had to go back and > rework a few statements (surprisingly tedious) to make it work. Things > would break and it was somewhat troublesome to step through > > 3. Fix (f.) at the end, so you can still use the named versions in > debugging or test code > > 4. Use more test cases (need to do more of this). Ideally each tacit > expression has a test case accompanied with it so when something goes > wrong you can go back and check the work. > > Something like this: > http://www.jsoftware.com/pipermail/programming/2014-July/038316.html > > > 5. Too many parentheses. Is there a way to eliminate unnecessary > parens automatically? I find myself throwing them in just in case > > 6. Use more helpers to reduce visual clutter - I'm sure this will come > with practice > > 7. When to amend vs reconstruct. I think I have many opportunities to > use an item amend instead of rebuilding the struct with a single new > value > > op_push =: (pC {:: ]) ; (pIP {:: ]) ; '' ; (<@: ((0{[) , getStack)) > > That can be written with an item amend and might be more clear > > > > Aside from all that, it was really quite fun and I was impressed by > what can be accomplished in such a terse, pure manner. The style of > composing it can still make it very readable.. > > One of the cooler things I realized was how I could pop from the stack > twice (or as many times as needed) with this expression: > > pop2=: [: ([ ( (pC{::]) ; (pIP{::]) ; ((pV{::]) , (pV{::[)) ; (pS{::]) > ) op_pop)^:2 ] > > which repeatedly pops and overwrites the 2nd item in the struct with a > running list of the popped values. I spent about 10 minutes trying to > make that a popn that let it take an argument of the times to pop but > then things started to get tricky when mixing valences. Anyhow, good > stuff! > > Thanks again > Joe > > On Thu, Nov 12, 2015 at 7:34 PM, Jose Mario Quintana > <jose.mario.quint...@gmail.com> wrote: >> Joe, >> >> We currently are experimenting with a style variant that further simplifies >> writing tacit code using a current version of an Jx interpreter. One of >> the first verbs tested was the Universal Turing Machine that you referred >> in the Wiki. I was thinking about rewriting your Byte Code Interpreter >> tacitly this way but you beat me :) The Jx interpreter is still evolving >> but we might release another version in the future. >> >> Even if a Jx interpreter is employed to produce a tacit verb the latter may >> run on an official interpreter. A utm running this way and the script that >> produced it is shown below. >> >> I might still try to rewrite in this manner your Byte Code Interpreter; in >> the mean time, your tacit version is already in my collection. Thanks for >> sharing it. >> >> JVERSION >> Installer: j602a_win.exe >> Engine: j803/2014-10-19-11:11:11 >> Library: 6.02.023 >> >> ". noun define -. CRLF NB. Fixed tacit universal Turing machine >> code... >> >> utm=. >> >> (((":@:(]&:>)@:(6&({::)) ,: (":@:] 9&({::))) ,. ':'"_) ,. 2&({::) >>>@:(((48"_ + ]) { a."_)@:[ ; (] $ ' '"_) , '^'"_) 3&({::))@:(-^:_@ >> :1:^:(-.@:(_1"_ = 1&({::))))@:((<@:(1 + 9&({::)) (,9)} ])@:(<@:(3& >> ({::) + 8&({::)) (,3)} ])@:(<@:((0: 0&({::)@:]`(<@:(1&({::))@:])`( >> 2&({::)@:])} ])@:(7 3 2&{)) (,2)} ])@:(<"0@:(6&({::) (<@:[ { ]) 0& >> ({::)) 7 8 1} ])@:([ 1!:2&2@:([ 11!:0@:('msgs'"_))@:(((":@:(]&:>)@ >> :(6&({::)) ,: (":@:] 9&({::))) ,. ':'"_) ,. 2&({::) >@:(((48"_ + ] >> ) { a."_)@:[ ; (] $ ' '"_) , '^'"_) 3&({::))^:(0 = 4&({::) | 9&({: >> :)))@:(<@:(1&({::) ; 3&({::) { 2&({::)) (,6)} ])@:((<@:0: (,3)} ]) >> ^:(0 = 1 + 3&({::)))@:((<@:(2&({::) , 5&({::)) (,2)} ])^:(3&({::) >> = #@:(2&({::))))@:((<@:(5&({::) , 2&({::)) (,2)} ])^:(_1 = 3&({::) >> ))^:(-.@:(_1"_ = 1&({::)))^:_)@:(<@:((({. , ({: % 3:) , 3:)@:$ $ , >> )@:(}."1)@:(".;._2)@:(0&({::))) (,0)} ])@:(<@:0: 5 9} ])@:(<@:('' >> , 2&({::)) (,2)} ])@:('B M PRINT MOVE C'&(] , ;:@:[))@:(,~) >> >> ) >> >> >> >> NB. A classic program. >> NB. 0 Tape Symbol Scan >> NB. S p m g >> QS=. (noun define) ; 0 NB. Reading the transition table >> and setting the state >> 0 24 1 1 >> 1 53 1 2 >> 2 60 1 3 >> 3 60 1 4 >> 4 63 1 5 >> 5 _16 1 6 >> 6 71 1 7 >> 7 63 1 8 >> 8 66 1 9 >> 9 60 1 10 >> 10 52 1 11 >> 11 _15 1 _1 >> ) >> >> >> TPF=. 0 ; 0 ; 1 NB. Setting the tape, its pointer >> and the display frequency >> >> TPF utm QS NB. Runing a classic program >> 0 0:0 >> 0 :^ >> 1 0:H0 >> 1 : ^ >> 2 0:He0 >> 2 : ^ >> 3 0:Hel0 >> 3 : ^ >> 4 0:Hell0 >> 4 : ^ >> 5 0:Hello0 >> 5 : ^ >> 6 0:Hello 0 >> 6 : ^ >> 7 0:Hello w0 >> 7 : ^ >> 8 0:Hello wo0 >> 8 : ^ >> 9 0:Hello wor0 >> 9 : ^ >> 10 0:Hello worl0 >> 10 : ^ >> 11 0:Hello world0 >> 11 : ^ >> 11 0:Hello world! >> 12 : ^ >> >> >> This is the Jx script that produced utm (using a pre-loaded tool set): >> >> NB. Universal Tacit Turing Machine >> >> NB. utm (dyadic verb) >> >> Set [tp ; LOCAL=. [tp >> >> NB. L... >> B - Blank Defaults >> M - State and Tape Symbol Holder >> PRINT - Printing Symbol >> MOVE - Tape Head Moving Instruction >> C - Step Counter >> ) >> >> NB. Y... >> Q - Instruction Table >> S - Turing Machine State >> NB. X... >> T - Data Tape >> P - Head Position Pointer >> F - Displaying Frequency >> ) >> >> rt=. ((({. , ({: % 3:) , 3:) o $) $ ,) o (}."1) o (". ;. _2) >> NB. Reshape transition table as a 3D array (state-symbol-action) >> >> DisplayTape=. > o (((48 c + ]) { a.c)x ; ((] $ ' 'c) , '^'c)) >> NB. Display Tape (verb) (e.g., T DisplayTape P) >> display=. ((((": o (]&:>) o M) ,: (":y C)) ,. ':'c ),.(T DisplayTape P)) >> NB. Displaying state, symbol, tape / step and pointer >> >> >> NB. utm (not in-place)... >> >> execute=. [tv >> (T h (B , T)) t (_1 = P) NB. Adjusting the tape's left hand >> side if >> NB. necessary (using lazy evaluation) >> (T h ( T , B)) t (P = # o T ) NB. Appending >> (P h 0:) t (0 = 1 + P) NB. Adjusting the pointer if >> necessary (lazy version) >> M h ( S ; (P { T) ) NB. Updating the state and reading >> the tape symbol >> [ (screen o display) t (0 = F | C ) NB. Displaying intermediate cycles >> >> (PRINT MOVE S) h (<"0 o (M bi Q) ) NB. Setting the actions >> T h ( amend o ((PRINT P T)ff) ) NB. Printing symbol on tape >> P h ( P + MOVE ) NB. Moving the pointer (if necessary) >> C h ( 1 + C ) NB. Increasing the counter >> ) >> >> halt=. _1 c = S NB. Halting when the current state is >> _1 >> InfiniteRegress=. (-^:_) o 1: t (-. o halt) >> NB. Alternatively: >> NB. ][ screen o ('A trivial infinite regress event.'c) t (-. o halt) >> >> utm=. [tv f. NB. Fixing the tacitly defined >> TuringMachine >> ,~ NB. Dyadic form (e.g., TPF >> TuringMachine QS ) >> LOCAL ln NB. Making room for local boxes (B M >> PRINT MOVE C) >> T h ( '' , T ) NB. Forcing the tape to be a list >> (B C) h (< o 0:) NB. Setting local B (empty defaults) >> and counter as 0 >> Q h (rt o Q) NB. Reshaping the transition table >> execute whilst (-. o halt) NB. Executing instructions the Turing >> machine program >> InfiniteRegress NB. Detecting an infinite regress >> event >> display >> ) >> >> utm wrap >> >> >> >> >> >> On Thu, Nov 12, 2015 at 3:59 PM, Joe Bogner <joebog...@gmail.com> wrote: >> >>> I've added a pure functional tacit version: >>> >>> http://code.jsoftware.com/wiki/User:Joe_Bogner/ByteCodeInterpreter#Tacit_Version >>> >>> Here's a silly proof: >>> >>> NB. wrapped at 50 characters so line fees shouldn't cause issues >>> >>> run =: ; <;._2 (0 : 0) >>> (0&{ , >:@:(1 {:: ]) ; 2&}.)@:(((1 {:: ]) { [) ((0 >>> {:: ]) ; (1 {:: ]) ; {.@:(3 {:: ]) ; }.@:(3 {:: ] >>> ))`((0 {:: ]) ; (1 {:: ]) ; '' ; <@:((0 { [) , 3 { >>> :: ]))`]`(+/@:}.@:[ ((0 {:: ]) ; (1 {:: ]) ; '' ; >>> <@:((0 { [) , 3 {:: ])) ])`([: (([: *@-~/ 2&({::)) >>> ((0 {:: ]) ; (1 {:: ]) ; '' ; <@:((0 { [) , 3 {:: >>> ])) ]) [: ([ ((0 {:: ]) ; (1 {:: ]) ; ((2 {:: ]) >>> , 2 {:: [) ; 3 {:: ]) (0 {:: ]) ; (1 {:: ]) ; {.@: >>> (3 {:: ]) ; }.@:(3 {:: ]))^:2 ])`((0 {:: ]) ; _ ; >>> '' ; 3 {:: ])`]`]`([ (<@:(2&{."1@:(0 {:: ]) i. 6 , >>> 1 {:: [) 1} ])^:(1 = 2 {:: ]) (0 {:: ]) ; (1 {:: >>> ]) ; {.@:(3 {:: ]) ; }.@:(3 {:: ]))`(([: (0 0 $ 1! >>> :2&2)@({"_)&(<;._1 '|exiting|greater than') 1&({:: >>> )@:[) ] ])@.(0 {:: [) ])^:(1 = (1 {:: ]) < <:@:#@: >>> [)^:_ (] ;&(0;'';'')) >>> ) >>> >>> >>> This program will add 6 and 5 together, pop the result into the >>> current value register and then exit >>> >>> (; run) (128!:2) (3 6 5),(0 0 0),:(9 0 0) >>> >>> >>> The resulting frame is the program, instruction pointer, current >>> value, and stack (empty) >>> >>> >>> +-----+-+--++ >>> |3 6 5|2|11|| >>> |0 0 0| | || >>> |9 0 0| | || >>> +-----+-+--++ >>> >>> >>> Further demonstration of the power of J's tacit engine. A toy >>> interpreter like this shows we can write code in an explicit >>> mini-language and have it run tacitly. I'm not sure of practical uses >>> and I'm not advocating using this for anything serious. J's tacit >>> engine acts as a virtual machine for the byte code. >>> >>> On Tue, Nov 10, 2015 at 4:57 PM, 'Pascal Jasmin' via Programming >>> <programm...@jsoftware.com> wrote: >>> > J is arguably already bytecode... ascii. And fairly terse. >>> > >>> > an extension to this: >>> > >>> http://code.jsoftware.com/wiki/User:PascalJasmin/JON_assignment_free_pure_functional_DSL >>> > >>> > would be to use instead of an assignment system, an object that is a >>> combination of queue, stack and dictionary that stores and retrieves >>> results. >>> > >>> > >>> > >>> > >>> > ----- Original Message ----- >>> > From: Joe Bogner <joebog...@gmail.com> >>> > To: programm...@jsoftware.com >>> > Cc: >>> > Sent: Tuesday, November 10, 2015 4:49 PM >>> > Subject: Re: [Jprogramming] essay: toy byte code interpreter >>> > >>> > Thanks. I don't have any application of it yet other than demystifying >>> > the concept of a bytecode interpretation. It does open up some >>> > interesting options of doing cool stuff with stacks in J. >>> > >>> > I am also thinking it would be a neat hack to implement a subset of J >>> > in J using interpreted bytecode. I would then probably write an >>> > interpreter of the bytecode in another language too for fun. >>> > >>> > >>> > >>> > >>> > >>> > On Tue, Nov 10, 2015 at 4:33 PM, 'Pascal Jasmin' via Programming >>> > <programm...@jsoftware.com> wrote: >>> >> Its cool. >>> >> >>> >> is your interest to do cool stuff with stacks in J, make a stack >>> language or interpret bytecode? >>> >> >>> >> >>> >> If its the first, I have many suggestions. >>> >> >>> >> >>> >> ________________________________ >>> >> From: Joe Bogner <joebog...@gmail.com> >>> >> To: programm...@jsoftware.com >>> >> Sent: Tuesday, November 10, 2015 4:07 PM >>> >> Subject: [Jprogramming] essay: toy byte code interpreter >>> >> >>> >> >>> >> I wrote this over lunch today and was pleased to see how simple it >>> >> was. I'm posting here for those who don't follow Recent Changes. >>> >> Feedback welcome >>> >> >>> >> http://code.jsoftware.com/wiki/User:Joe_Bogner/ByteCodeInterpreter >>> >> >>> >> I'd be interested in any speedups to the timing test that still permit >>> >> jumps. It's fine as-is for a toy though >>> >> ---------------------------------------------------------------------- >>> >> 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 >>> ---------------------------------------------------------------------- >>> 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 ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm