This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-12-20
Channels
- # adventofcode (23)
- # announcements (4)
- # babashka (1)
- # beginners (37)
- # biff (2)
- # calva (1)
- # cider (19)
- # clj-kondo (11)
- # clojure (45)
- # clojure-bay-area (2)
- # clojure-europe (12)
- # clojure-nl (1)
- # clojure-norway (15)
- # clojure-uk (2)
- # clojurescript (8)
- # conjure (1)
- # cursive (17)
- # datomic (11)
- # garden (1)
- # graalvm (4)
- # hyperfiddle (21)
- # java (10)
- # jobs (3)
- # lsp (23)
- # off-topic (18)
- # polylith (2)
- # re-frame (4)
- # releases (1)
- # remote-jobs (3)
- # rewrite-clj (4)
- # squint (44)
- # uncomplicate (1)
- # xtdb (84)
Hey š, I'm trying to play around with https://motioncanvas.io/ in squint.
It requires using function*
generators with yield*
s.
I can write a macro to output yield*
s but I can't figure out how to output a function*
with a inline body.
Any tips on that? Pointers in more sane directions are also appreciated š
That's what I've been trying, but I'm not sure how to actually get a body into the function :thinking_face: This get's close:
(defmacro my-fn [[& params] & body]
`(js* "function* ~{} {\n~{}\n}"
~params
(do ~@body)))
But there's an extra (function() {xxx})()
wrapperIt actually produced the same output without un-namespacing the *js
:thinking_face:
I'm opening an issue now š
Thanks for your time š
At that point it's better to just not use squint for now. I'm only playing so I can come back to it later š
sure. the function*
might be difficult in combination with do and let expressions since they use IIFEs. I haven't tested this yes, but something like:
(defn ^:* foo []
(js-yield 1)
(js-yield* [1 2 3])
(let [x 1 _ (js-yield 2)]
(js-yield x)
(do 1 2 (js-yield 3) 4))
will compile into:
function* foo() {
yield 1;
yield* [1 2 3];
(function() ...)()
(function() ...)()
}
Yeah, that's not ideal :thinking_face:
I don't think you can, my editor complains at the very least
the same is true for async but that is a solved problem, the solution in squint it to make those IIFEs async too
If that were the route you went down I think you could prefix the iife with a yield*
too
it is a similar problem with async, except with a generator IIFE I don't know for sure if a user is going to be using the return value of the IIFE or simple will use yield. e.g.:
(let [x (let [y (do (js-yield 1) 5)] y)] (js-yield x))
in the async case I simply added a await
before the IIFE which is sufficient to cover all cases, even if you don't use js-await inside of the IIFE
function* foo () {
yield 1;
yield* [2, 3];
let x = (function* () {
yield 6;
yield* [7, 8, 9];
return "This is X";
})();
while(true) {
const { value, done } = x.next();
if (done) {
x = value;
break;
} else {
yield value;
}
}
console.log('x', x);
}
Some thoughts:
ā¢ Would it be possible for a user to have access to x
while it's still a generator, say if something in it threw an exception?
ā¢ If a js-yield
is the last statement in the do
would it generate return yield value
? This is fine but x
ends up undefined
If it's possible: this depends on how it gets implemented. Write out the JS and we'll find out :)
(let [x (do (js-yield ..) 1)] ...)
in this code there is no way to see x
as a generator so I don't think that makes senseThese seemed like some fairly natural expansions: https://gist.github.com/Akeboshiwind/f55646c8e98793ec27af84506bd7969d
Wrapping the do
with a try
seemed like a problem case :thinking_face:
But maybe I'm missing something better
I suppose in that case I would expect the catch
to set the value of x
so that should be fine too :thinking_face:
I think your try/catch case works like expected, since in the catch there is no return value so x remains undefined
Yup, if I put a 7
at the end of the catch
then I can see how that'd work as I expected š