google / clojure-turtle

A Clojure library that implements the Logo programming language in a Clojure context
Apache License 2.0
425 stars 41 forks source link

Update core.cljc #14

Closed atrus159 closed 8 years ago

atrus159 commented 8 years ago

Added a (wait [ms]) function that takes a number of milliseconds and sleeps for that long. Can be used in a repeat loop to show steps execute in real time.

echeran commented 8 years ago

Good work, @atrus159 ! I tested it out in the Java Clojure REPL, and the functionality is as desired: the thread effectively sleeps only once. In Java, the simplest way would have been to call Thread.sleep(ms);, which is (Thread/sleep ms) in Clojure. But I realized how weird sleep must be implemented in JavaScript (in non-user facing code), and your code already captures that implementation hack.

Okay, that being said, the one hitch is that the code doesn't seem to work in the CLJS REPL, at least the one that I pull up with lein figwheel as mentioned in the main Readme. I think your solution is halfway there. Can you see if you can fix it? I'll leave it as an 'exercise' for you, but email me if you get stuck. The following links are hints, if you need them: mimicking sleep in JS and ClojureScript syntax for JS Date And you'll probably need to use reader conditionals syntax.

You can either create a new commit or update your commit. Creating a new commit and pushing should be straightforward. To update your commit, you can make your changes on your local working copy, do git add, then do git --amend. That will make your local copy's master branch diverge with your Github fork's master branch, so you will have to do a force push from local to your Github fork repo -- git push -f.

atrus159 commented 8 years ago

Hi, I ran it through a REPL and it worked, but I was using "lein repl" as my start command, so I'm not sure if I can reproduce it. I will make a change that uses the java method though.

On Thu, Mar 10, 2016 at 12:15 AM, Elango notifications@github.com wrote:

Good work, @atrus159 https://github.com/atrus159 ! I tested it out in the Java Clojure REPL, and the functionality is as desired: the thread effectively sleeps only once. In Java, the simplest way would have been to call Thread.sleep(ms);, which is (Thread/sleep ms) in Clojure. But I realized how weird sleep must be implemented in JavaScript (in non-user facing code), and your code already captures that implementation hack.

Okay, that being said, the one hitch is that the code doesn't seem to work in the CLJS REPL, at least the one that I pull up with lein figwheel as mentioned in the main Readme. I think your solution is halfway there. Can you see if you can fix it? I'll leave it as an 'exercise' for you, but email me if you get stuck. The following links are hints, if you need them: mimicking sleep in JS http://stackoverflow.com/a/17936490/2077918 and ClojureScript syntax for JS Date http://stackoverflow.com/questions/27740676/how-do-you-get-a-timestamp-in-clojurescript And you'll probably need to use reader conditionals http://clojure.org/guides/reader_conditionals syntax.

You can either create a new commit or update your commit. Creating a new commit and pushing should be straightforward. To update your commit, you can make your changes on your local working copy, do git add, then do git --amend. That will make your local copy's master branch diverge with your Github fork's master branch, so you will have to do a force push from local to your Github fork repo -- git push -f.

— Reply to this email directly or view it on GitHub https://github.com/google/clojure-turtle/pull/14#issuecomment-194725483.

atrus159 commented 8 years ago

gonna go download flywheel and see if I can get it working

On Thu, Mar 10, 2016 at 10:26 AM, Darius Rudominer darius.is.ru@gmail.com wrote:

Hi, I ran it through a REPL and it worked, but I was using "lein repl" as my start command, so I'm not sure if I can reproduce it. I will make a change that uses the java method though.

On Thu, Mar 10, 2016 at 12:15 AM, Elango notifications@github.com wrote:

Good work, @atrus159 https://github.com/atrus159 ! I tested it out in the Java Clojure REPL, and the functionality is as desired: the thread effectively sleeps only once. In Java, the simplest way would have been to call Thread.sleep(ms);, which is (Thread/sleep ms) in Clojure. But I realized how weird sleep must be implemented in JavaScript (in non-user facing code), and your code already captures that implementation hack.

Okay, that being said, the one hitch is that the code doesn't seem to work in the CLJS REPL, at least the one that I pull up with lein figwheel as mentioned in the main Readme. I think your solution is halfway there. Can you see if you can fix it? I'll leave it as an 'exercise' for you, but email me if you get stuck. The following links are hints, if you need them: mimicking sleep in JS http://stackoverflow.com/a/17936490/2077918 and ClojureScript syntax for JS Date http://stackoverflow.com/questions/27740676/how-do-you-get-a-timestamp-in-clojurescript And you'll probably need to use reader conditionals http://clojure.org/guides/reader_conditionals syntax.

You can either create a new commit or update your commit. Creating a new commit and pushing should be straightforward. To update your commit, you can make your changes on your local working copy, do git add, then do git --amend. That will make your local copy's master branch diverge with your Github fork's master branch, so you will have to do a force push from local to your Github fork repo -- git push -f.

— Reply to this email directly or view it on GitHub https://github.com/google/clojure-turtle/pull/14#issuecomment-194725483 .

atrus159 commented 8 years ago

Hi, I think I got flywheel to work, but I ran it on the vanilla code and wasn't able to get repeat to work there either. On the code I copied from the git-hub I ran the following command taken from your tutorial:

(repeat 3 (all (forward 30) (right 90)))

And received the following complaint:

"WARNING: Wrong number of args (2) passed to clojure-turtle.core/repeat at line 1

(cljs.core/let [states19252auto (cljs.core/repeatedly nil)](cljs.core/dorun states19252auto) (cljs.core/last states19252auto__))" In addition, the turtle moved a single stage in the repeat but no farther. Can you confirm that Figwheel works just in general on your setup? If so, its probably a problem with my set-up of figwheel.

On Thu, Mar 10, 2016 at 10:48 AM, Darius Rudominer darius.is.ru@gmail.com wrote:

gonna go download flywheel and see if I can get it working

On Thu, Mar 10, 2016 at 10:26 AM, Darius Rudominer <darius.is.ru@gmail.com

wrote:

Hi, I ran it through a REPL and it worked, but I was using "lein repl" as my start command, so I'm not sure if I can reproduce it. I will make a change that uses the java method though.

On Thu, Mar 10, 2016 at 12:15 AM, Elango notifications@github.com wrote:

Good work, @atrus159 https://github.com/atrus159 ! I tested it out in the Java Clojure REPL, and the functionality is as desired: the thread effectively sleeps only once. In Java, the simplest way would have been to call Thread.sleep(ms);, which is (Thread/sleep ms) in Clojure. But I realized how weird sleep must be implemented in JavaScript (in non-user facing code), and your code already captures that implementation hack.

Okay, that being said, the one hitch is that the code doesn't seem to work in the CLJS REPL, at least the one that I pull up with lein figwheel as mentioned in the main Readme. I think your solution is halfway there. Can you see if you can fix it? I'll leave it as an 'exercise' for you, but email me if you get stuck. The following links are hints, if you need them: mimicking sleep in JS http://stackoverflow.com/a/17936490/2077918 and ClojureScript syntax for JS Date http://stackoverflow.com/questions/27740676/how-do-you-get-a-timestamp-in-clojurescript And you'll probably need to use reader conditionals http://clojure.org/guides/reader_conditionals syntax.

You can either create a new commit or update your commit. Creating a new commit and pushing should be straightforward. To update your commit, you can make your changes on your local working copy, do git add, then do git --amend. That will make your local copy's master branch diverge with your Github fork's master branch, so you will have to do a force push from local to your Github fork repo -- git push -f.

— Reply to this email directly or view it on GitHub https://github.com/google/clojure-turtle/pull/14#issuecomment-194725483 .

echeran commented 8 years ago

Yep, that error occurs in the ClojureScript REPL... clojure-turtle's repeat and all are implemented as macros, and macros don't work as seamlessly in CLJS as they do in regular Java Clojure. I filed issue #15 in hopes that we can solicit help there.

In the meantime, in order to write code that works the same both in a Clojure REPL and ClojureScript REPL, you might be able to use dotimes as a substitute for repeat, and just create a regular function as a substitute for all. The return value of an all form is actually a function, anyways.

atrus159 commented 8 years ago

Hi, sorry I have not been in communication for a while. I do not seem to be able to add functions to the code that can be run by figwheel. I tried the simplest case of (defn foo [x](inc x)), and ran (foo 1) in both the repl and figwheel. In the repl it executed fine but in figwheel I received the following exception:

object[TypeError TypeError: Cannot read property 'call' of undefined]

I admit that I do not have a great understanding of how figwheel works, but this seems like there is something major I am missing if I can't even get this to work. Is this a known problem? Thanks.

On Thu, Mar 10, 2016 at 11:33 AM, Elango notifications@github.com wrote:

Yep, that error occurs in the ClojureScript REPL... clojure-turtle's repeat and all are implemented as macros, and macros don't work as seamlessly in CLJS as they do in regular Java Clojure. I filed issue #15 https://github.com/google/clojure-turtle/issues/15 in hopes that we can solicit help there.

In the meantime, in order to write code that works the same both in a Clojure REPL and ClojureScript REPL, you might be able to use dotimes as a substitute for repeat, and just create a regular function as a substitute for all. The return value of an all form is actually a function, anyways.

— Reply to this email directly or view it on GitHub https://github.com/google/clojure-turtle/pull/14#issuecomment-195011886.

echeran commented 8 years ago

Okay, that's strange. See the bottom of this comment for an explanation of how Figwheel creates a CLJS REPL. In order to troubleshoot, we should isolate variables. Let's start from the top. First, clone the repo fresh into a totally new directory so that we can see what it's like for other people who will also try this out for the first time. Also -- what version of Java are you running (what's the output of java -version) and what OS are you running on?

Let's test out a 'plain' CLJS REPL first. Try the following:

lein trampoline cljsbuild repl-rhino

(defn foo [x] (inc x))
(foo 1)

Then, afterwards, let's do the same, but with a Figwheel CLJS REPL: lein figwheel (open the URL in a browser -- this completes the connection and brings up the REPL in your terminal)

(defn foo [x] (inc x))
(foo 1)

I have no problems, personally with both above. If you do run into a problem, let me know the first point in the above sequence in which that occurs.

I'm running Oracle Java 1.8.0_71 64-bit on Mac OS X. People have run into limitations with OpenJDK

Figwheel creates a local server that serves up an HTML page, in which the HTML page will load a browser REPL (a CLJS REPL). Figwheel opens up a CLJS REPL session in the console that's connected (it's like a thin-client) to the browser REPL in that webpage. The connection to the browser CLJS REPL that Figwheel keeps open allows you to interactively interact with the browser at the REPL -- ex: run (js/alert "Hello, browser") This presentation on Figwheel is entertaining to watch: https://www.youtube.com/watch?v=j-kj2qwJa_E

echeran commented 8 years ago

Looks good -- the wait fn does what it's supposed to do. In the CLJS REPL, you can try:

clojure-turtle.core=> (do (wait 3000) (println "hello") (wait 3000))

...and you'll see the intended pausing behavior.

A separate issue is how the rendering event loop in either Processing.js or Quil is implemented. For whatever reason, for any code block with wait statements, all of the waiting is performed first, and then the rendering statements take effect at the very end. Ex:

(do (wait 3000) (forward 30) (wait 3000))

I'll create a separate issue regarding the puzzling behavior that we see in the CLJS version.