Awesome! I've been re-factoring my code but I am having difficulty figuring 
out how to deal with state without manipulating global state;  my first 
thought was to create a binding form within a doseq in a function that 
executed each instruction and mutated the cells when necessary--but that 
didn't work out.  I like your usage of multimethods to deal with each 
instruction, although as a beginner some parts of your code are difficult 
for me to follow.  This is shaping up to be a pretty good learning 
experience for me!  I think my mind is still stuck in an imperative mode of 
thinking, and it's helpful to look at the code of a more seasoned clojure 
programmer.

On Sunday, April 7, 2013 10:06:26 PM UTC-4, Michał Marczyk wrote:
>
> Incidentally, this thread made me feel a sudden desire to write my own 
> bf interpreter. Feel free to take a look at 
>
> https://github.com/michalmarczyk/bf.clj 
>
> if you'd like. :-) 
>
> Cheers, 
> Michał 
>
>
> On 7 April 2013 05:23, Sean Corfield <seanco...@gmail.com <javascript:>> 
> wrote: 
> > I agree. I see nothing that sets the code pointer back to the start of 
> the loop. 
> > 
> > I also agree with Michał's suggestion that getting rid of global state 
> > and making this more functional in style will make it much easier to 
> > read, debug and maintain - as it stands it not very idiomatic for 
> > Clojure. 
> > 
> > Sean 
> > 
> > On Sat, Apr 6, 2013 at 5:16 PM, Michał Marczyk 
> > <michal....@gmail.com<javascript:>> 
> wrote: 
> >> Not sure why you're using (- end-index 2) in the printed message. 
> >> Also, you can use (dec end-index) in your termination condition. 
> >> 
> >> As for the main problem, I haven't studied your program very closely, 
> >> but it seems to me that your program counter may never get reset to 
> >> the beginning of the loop, in which case the next call to 
> >> (exec-instruction end-loop) would start executing instructions just 
> >> past the end of the loop body. 
> >> 
> >> Cheers, 
> >> Michał 
> >> 
> >> 
> >> On 7 April 2013 01:49, Andrew Spano <werdn...@gmail.com <javascript:>> 
> wrote: 
> >>> Hello, I'm a new clojure programmer--but after learning a bit of 
> clojure 
> >>> including iteration, some core high order functions, and a little bit 
> about 
> >>> state management I decided to try my hand on a brainfuck interpreter. 
> >>> 
> >>> Located here: 
> >>> 
> https://github.com/recursor94/brainfuck.clj/blob/master/brainfuck/src/brainfuck/fuck.clj
>  
> >>> 
> >>> Handling looping complicated things.  And the way I chose to deal with 
> >>> looping resulted in some pretty ugly functions.  I hope to clean that 
> up in 
> >>> the future and refractor the code into a more functional style after 
> I've 
> >>> finished the first draft. 
> >>> 
> >>> The issue is in a particular function which never stops recuring even 
> when 
> >>> the condition for recuring is false: 
> >>> 
> >>> (defn exec-instruction 
> >>>   "executes each function in the codemap vector in sequential order" 
> >>> 
> >>> 
> >>>     ([end-index] 
> >>>        (inc-code-pos)  ;;side affect function that moves the code 
> pointer (I 
> >>> have both a code pointer and a data pointer in my interpreter) 
> >>>        (loop [index (:index @codemap)] 
> >>>          (let [codevec (@codemap :struct) 
> >>>                instruct (get codevec index)] 
> >>>            (println "index:" index 
> >>>                     "instruct" instruct 
> >>>                     "minus one index:" (- end-index 2)) 
> >>>            (instruct)) 
> >>>          (when-not (= index (- end-index 1)) 
> >>>            (println "yeah you are") 
> >>>            (inc-code-pos) 
> >>>            (recur (inc index))))) 
> >>> ;;end problem 
> >>>     ([] 
> >>>        (doseq [instruct (@codemap :struct)] 
> >>>          (instruct) ;;higher order functions ftw 
> >>>          (inc-code-pos)))) 
> >>> 
> >>> 
> >>> And here is the function that triggers this function: 
> >>> 
> >>> (defn begin-loop 
> >>>   "run through a loop until current cell drops to zero" 
> >>>   [] 
> >>>   (loop [loop-counter (@cells @pointer) 
> >>>          end-loop (find-end (@codemap :index)) ;;find-end returns an 
> integer 
> >>>          pos (@codemap :index)] 
> >>>     (println "cell counter:" loop-counter 
> >>>              "other:"  (@cells @pointer) 
> >>>              "at 0:" (@cells @pointer) 
> >>>              "also:" end-loop)  ;;debug output 
> >>>     (exec-instruction end-loop) 
> >>>     (when-not (= loop-counter 0) 
> >>>       (recur (@cells @pointer) end-loop pos)))) 
> >>> 
> >>> 
> >>> The program is supposed to stop when it reaches a closing end brace 
> and jump 
> >>> back to the opening brace in the code.  But the output indicates that 
> the 
> >>> program never gets passed the first iteration. 
> >>> 
> >>> For example, given this hello world brainfuck program: 
> >>> 
> >>> 
> >>> 
> ++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
>  
>
> >>> 
> >>> The program outputs the following: 
> >>> index: 11 instruct #'brainfuck.fuck/+pointer minus one index: 39 
> >>> yeah you are 
> >>> index: 12 instruct #'brainfuck.fuck/plus minus one index: 39 
> >>> yeah you are 
> >>> index: 13 instruct #'brainfuck.fuck/plus minus one index: 39 
> >>> yeah you are 
> >>> index: 14 instruct #'brainfuck.fuck/plus minus one index: 39 
> >>> yeah you are 
> >>> index: 15 instruct #'brainfuck.fuck/plus minus one index: 39 
> >>> yeah you are 
> >>> index: 16 instruct #'brainfuck.fuck/plus minus one index: 39 
> >>> yeah you are 
> >>> index: 17 instruct #'brainfuck.fuck/plus minus one index: 39 
> >>> yeah you are 
> >>> index: 18 instruct #'brainfuck.fuck/plus minus one index: 39 
> >>> yeah you are 
> >>> index: 19 instruct #'brainfuck.fuck/+pointer minus one index: 39 
> >>> yeah you are 
> >>> index: 20 instruct #'brainfuck.fuck/plus minus one index: 39 
> >>> yeah you are 
> >>> index: 21 instruct #'brainfuck.fuck/plus minus one index: 39 
> >>> yeah you are 
> >>> index: 22 instruct #'brainfuck.fuck/plus minus one index: 39 
> >>> yeah you are 
> >>> index: 23 instruct #'brainfuck.fuck/plus minus one index: 39 
> >>> yeah you are 
> >>> index: 24 instruct #'brainfuck.fuck/plus minus one index: 39 
> >>> yeah you are 
> >>> index: 25 instruct #'brainfuck.fuck/plus minus one index: 39 
> >>> yeah you are 
> >>> index: 26 instruct #'brainfuck.fuck/plus minus one index: 39 
> >>> yeah you are 
> >>> index: 27 instruct #'brainfuck.fuck/plus minus one index: 39 
> >>> yeah you are 
> >>> index: 28 instruct #'brainfuck.fuck/plus minus one index: 39 
> >>> yeah you are 
> >>> index: 29 instruct #'brainfuck.fuck/plus minus one index: 39 
> >>> yeah you are 
> >>> index: 30 instruct #'brainfuck.fuck/+pointer minus one index: 39 
> >>> yeah you are 
> >>> index: 31 instruct #'brainfuck.fuck/plus minus one index: 39 
> >>> yeah you are 
> >>> index: 32 instruct #'brainfuck.fuck/plus minus one index: 39 
> >>> yeah you are 
> >>> index: 33 instruct #'brainfuck.fuck/plus minus one index: 39 
> >>> yeah you are 
> >>> index: 34 instruct #'brainfuck.fuck/+pointer minus one index: 39 
> >>> yeah you are 
> >>> index: 35 instruct #'brainfuck.fuck/plus minus one index: 39 
> >>> yeah you are 
> >>> index: 36 instruct #'brainfuck.fuck/-pointer minus one index: 39 
> >>> yeah you are 
> >>> index: 37 instruct #'brainfuck.fuck/-pointer minus one index: 39 
> >>> yeah you are 
> >>> index: 38 instruct #'brainfuck.fuck/-pointer minus one index: 39 
> >>> yeah you are 
> >>> index: 39 instruct #'brainfuck.fuck/-pointer minus one index: 39 
> >>> yeah you are 
> >>> index: 40 instruct #'brainfuck.fuck/minus minus one index: 39 
> >>> cell counter: 9 other: 9 at 0: 9 also: 41 
> >>> index: 41 instruct #'brainfuck.fuck/end-loop minus one index: 39 
> >>> Exception in thread "main" java.lang.IllegalStateException: Attempting 
> to 
> >>> call unbound fn: #'brainfuck.fuck/end-loop 
> >>>       at clojure.lang.Var$Unbound.throwArity(Var.java:43) 
> >>>       at clojure.lang.AFn.invoke(AFn.java:35) 
> >>>       at clojure.lang.Var.invoke(Var.java:411) 
> >>>       at brainfuck.fuck$exec_instruction.invoke(fuck.clj:142) 
> >>>       at brainfuck.fuck$begin_loop.invoke(fuck.clj:94) 
> >>>       at clojure.lang.Var.invoke(Var.java:411) 
> >>>       at brainfuck.fuck$exec_instruction.invoke(fuck.clj:149) 
> >>>       at brainfuck.fuck$_main.invoke(fuck.clj:165) 
> >>>       at clojure.lang.Var.invoke(Var.java:411) 
> >>>       at user$eval218.invoke(NO_SOURCE_FILE:1) 
> >>>       at clojure.lang.Compiler.eval(Compiler.java:6511) 
> >>>       at clojure.lang.Compiler.eval(Compiler.java:6501) 
> >>>       at clojure.lang.Compiler.eval(Compiler.java:6477) 
> >>>       at clojure.core$eval.invoke(core.clj:2797) 
> >>>       at clojure.main$eval_opt.invoke(main.clj:297) 
> >>>       at clojure.main$initialize.invoke(main.clj:316) 
> >>>       at clojure.main$null_opt.invoke(main.clj:349) 
> >>>       at clojure.main$main.doInvoke(main.clj:427) 
> >>>       at clojure.lang.RestFn.invoke(RestFn.java:421) 
> >>>       at clojure.lang.Var.invoke(Var.java:419) 
> >>>       at clojure.lang.AFn.applyToHelper(AFn.java:163) 
> >>>       at clojure.lang.Var.applyTo(Var.java:532) 
> >>>       at clojure.main.main(main.java:37) 
> >>> 
> >>> 
> >>> Aside from too much incidental complexity, I can't figure out what I 
> did 
> >>> wrong here and why the loop never seems to stop iterating when it 
> clearly 
> >>> should.  Any help at all is sincerely appreciated.  In fact, I'd love 
> any 
> >>> pointers about the program structure itself if you care to take a look 
> at my 
> >>> github. 
> >>> 
> >>> Thanks, 
> >>> 
> >>> --Andrew 
> >>> 
> >>> -- 
> >>> -- 
> >>> You received this message because you are subscribed to the Google 
> >>> Groups "Clojure" group. 
> >>> To post to this group, send email to clo...@googlegroups.com<javascript:> 
> >>> Note that posts from new members are moderated - please be patient 
> with your 
> >>> first post. 
> >>> To unsubscribe from this group, send email to 
> >>> clojure+u...@googlegroups.com <javascript:> 
> >>> For more options, visit this group at 
> >>> http://groups.google.com/group/clojure?hl=en 
> >>> --- 
> >>> You received this message because you are subscribed to the Google 
> Groups 
> >>> "Clojure" group. 
> >>> To unsubscribe from this group and stop receiving emails from it, send 
> an 
> >>> email to clojure+u...@googlegroups.com <javascript:>. 
> >>> For more options, visit https://groups.google.com/groups/opt_out. 
> >>> 
> >>> 
> >> 
> >> -- 
> >> -- 
> >> You received this message because you are subscribed to the Google 
> >> Groups "Clojure" group. 
> >> To post to this group, send email to clo...@googlegroups.com<javascript:> 
> >> Note that posts from new members are moderated - please be patient with 
> your first post. 
> >> To unsubscribe from this group, send email to 
> >> clojure+u...@googlegroups.com <javascript:> 
> >> For more options, visit this group at 
> >> http://groups.google.com/group/clojure?hl=en 
> >> --- 
> >> You received this message because you are subscribed to the Google 
> Groups "Clojure" group. 
> >> To unsubscribe from this group and stop receiving emails from it, send 
> an email to clojure+u...@googlegroups.com <javascript:>. 
> >> For more options, visit https://groups.google.com/groups/opt_out. 
> >> 
> >> 
> > 
> > 
> > 
> > -- 
> > Sean A Corfield -- (904) 302-SEAN 
> > An Architect's View -- http://corfield.org/ 
> > World Singles, LLC. -- http://worldsingles.com/ 
> > 
> > "Perfection is the enemy of the good." 
> > -- Gustave Flaubert, French realist novelist (1821-1880) 
> > 
> > -- 
> > -- 
> > You received this message because you are subscribed to the Google 
> > Groups "Clojure" group. 
> > To post to this group, send email to clo...@googlegroups.com<javascript:> 
> > Note that posts from new members are moderated - please be patient with 
> your first post. 
> > To unsubscribe from this group, send email to 
> > clojure+u...@googlegroups.com <javascript:> 
> > For more options, visit this group at 
> > http://groups.google.com/group/clojure?hl=en 
> > --- 
> > You received this message because you are subscribed to the Google 
> Groups "Clojure" group. 
> > To unsubscribe from this group and stop receiving emails from it, send 
> an email to clojure+u...@googlegroups.com <javascript:>. 
> > For more options, visit https://groups.google.com/groups/opt_out. 
> > 
> > 
>

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to