clojurescript

borkdude 2026-05-18T14:08:18.338879Z

https://clojurescript.org/reference/async-functions

🆒 4
❤️ 1
🎉 17
Macroz 2026-05-19T15:33:03.292629Z

I think the docs are not very explicit about whether this variant also works

(fn ^:async foo [urls] ,,,)
because they only use
(^:async fn foo [urls] ,,,)

borkdude 2026-05-19T15:41:21.504449Z

good point. @dnolen could you make this small modification?

dnolen 2026-05-19T16:04:01.003229Z

like add one more invalid case?

Macroz 2026-05-19T16:05:22.347809Z

If that's invalid then this needs a bit of work? > Define an async function by placing :async metadata either on the fn symbol or on the name of the function.

Macroz 2026-05-19T16:05:51.278489Z

By just reading the documentation, I can't say should it work or not.

borkdude 2026-05-19T16:22:13.010659Z

no it's not invalid

borkdude 2026-05-19T16:22:25.838389Z

just confusing because of the name foo which isn't mandatory

dnolen 2026-05-19T16:25:25.716529Z

done

Macroz 2026-05-19T16:30:44.854549Z

Yes I'm explicitly referring to naming fn and having a name like foo is from my point of view a mandatory example. Now the example is again confusing me as it's an anonymous function without name and with ^:async in two valid places.

(^:async fn [n]

(fn ^:async [n]
The second isn't obvious to me based on the text.

Macroz 2026-05-19T16:31:29.416669Z

It is hair-splitting for sure but good documentation is good 🙂

Macroz 2026-05-19T16:32:45.726109Z

The examples will be scraped and forever etched into the weights of the clankers. Along with the right and wrong code from the repos.

borkdude 2026-05-19T16:37:07.370259Z

@dnolen I think a mistake was made. this one is invalid but is now listed as valid code:

(fn ^:async [n]
  (let [x (await (js/Promise.resolve 10))]
    (+ n x)))
The point was just that in the (fn foo []) cases, the name foo should not be there since it's irrelevant. There's one such case left:
^:async (fn foo [urls] ,,,)

thheller 2026-05-19T16:38:11.783589Z

I think it would help and be more consistent if all example used (^:async fn [n] ...) regardless of name used or not. that how I'm personally going to use it anyway. good that it works on name too, but consistency is better imho

borkdude 2026-05-19T16:38:18.988379Z

and while we're at it: the use of js/Promise and js/fetch vs Promise + fetch with refer-globals feels a bit inconsistent

borkdude 2026-05-19T16:38:44.110329Z

yes, all non-top-level fns in the docs should be without a name, to just not confuse users

thheller 2026-05-19T16:39:10.748929Z

(^:async defn foo [] ...) doesn't work by any chance right? didn't check

Macroz 2026-05-19T16:39:40.842879Z

I like to name most important anonymous functions as it makes traces better.

borkdude 2026-05-19T16:40:47.483199Z

probably doesn't work, but haven't tested.

dnolen 2026-05-19T16:48:36.627309Z

@borkdude oops, sorry maybe a PR is in order, I'm a bit distracted at the moment

borkdude 2026-05-19T16:48:59.518799Z

will do, but busy tonight

👍🏽 1
exitsandman 2026-05-19T17:29:21.282289Z

<bikeshedding about async on argv>

thheller 2026-05-19T17:31:44.525079Z

problem is where to place the async tag on multi artiy fns (fn (^:async [a] ...) ([a b] ...)). this would be partially async or implied async for all? js doesn't have this and fwiw its also never on the arguments 😉

dnolen 2026-05-19T17:46:26.488489Z

that I'm pretty sure does not work at all right now? that should be called out

borkdude 2026-05-19T17:47:22.764389Z

it does not work. that is why we don't allow the async tag on the arg vec.

borkdude 2026-05-19T17:47:34.926509Z

and that is why it is labeled as invalid in the reference

thheller 2026-05-19T17:48:09.117949Z

yeah I just gave an example for why its not on the arg vector in response to exitsandman

👍 1
borkdude 2026-05-19T17:51:23.112119Z

we can include this in the reference why this was decided, but maybe it's more something for JIRA

dnolen 2026-05-19T18:02:22.643839Z

this should just be called out explicitly as not supported for now

borkdude 2026-05-19T18:03:30.876699Z

isn't that already (argvec) or do you mean multi-arity? if latter, will add tomorrow

dnolen 2026-05-19T18:11:22.975739Z

multi-arity

👍 1
exitsandman 2026-05-19T19:16:19.929009Z

fwiw I was under the impression that something along the lines of

(defn foo
  ([a] (foo a 3))
  (^:async [a b] (+ a b)))
compiling into something like (this is a sketch ofc)
function foo(a1, a2)
{
  switch(arguments.length)
  {
    // however cljs arities are handled
    case 1: return foo(a1);
    case 2: return (async function (a, b) { return a + b; })(a1, a2);
    default: ...
  }
}
would work fine. As per the "async-ness" being part of the function arity rather than the whole function and the difference with JS syntax, consider clj type hints. I mostly deleted the comment because I thought it didn't add much to the practical discussion

dnolen 2026-05-19T19:22:24.608589Z

supporting multi-arity functions is probably a lot more effort than it might appear, it's definitely a different bucket, and unclear how much that bucket is leaking 🙂

exitsandman 2026-05-19T19:22:37.404909Z

yeah