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