leonoel / cloroutine

Coroutine support for clojure
Eclipse Public License 2.0
228 stars 10 forks source link

Generator in guide1 doesn't work in clojurescript #3

Closed guruma closed 5 years ago

guruma commented 5 years ago

I wrote the following code according to the guide generators

(ns generator
  (:require [cloroutine.core :refer [cr]]))

(def ^:dynamic *tail*)

(defn gen-seq [gen]
  (binding [*tail* (lazy-seq (gen-seq gen))] (gen)))

(defn yield [x]
  (cons x *tail*))

(defn no-op [])

(defmacro generator [& body]
  `(gen-seq (cr {yield no-op} ~@body nil)))

(defn -main [& args]
  (println (generator
             (yield :a)
             (yield :b)
             (yield :c))) )

Then I ran the code like this and get the result.

$clj -m cljs.main -re node -m generator
(generator/gen-seq (cloroutine.core/cr {generator/yield generator/no-op} (:c) nil))

The actual result is not same as the expected result on the guide which is [:a :b :c].

leonoel commented 5 years ago

clojurescript macros must be declared in a separate clojure namespace otherwise they're treated as functions. Try moving generator to a sibling .clj file.

guruma commented 5 years ago

Oh. It's my fault! You're right.

I chagned the source like this and it works.

; generator_definition.cljc
(ns generator-definition
  (:require [cloroutine.core :refer [cr]]))

(def ^:dynamic *tail*)

(defn gen-seq [gen]
  (binding [*tail* (lazy-seq (gen-seq gen))] (gen)))

(defn yield [x]
  (cons x *tail*))

(defn no-op [])

(defmacro generator [& body]
  `(gen-seq (cr {yield no-op} ~@body nil)))
; generator_test.cljs
(ns generator-test
  (:require [generator-definition :refer [yield] :refer-macros [generator]]))

(defn -main [& args]
  (println (generator
             (yield :a)
             (yield :b)
             (yield :c))) )
$clj -m cljs.main -re node -m generator-test
(:a :b :c)

It's cool!