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

Reply via email to