This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-02-11
Channels
- # architecture (1)
- # babashka (61)
- # babashka-sci-dev (1)
- # beginners (85)
- # calva (112)
- # clj-kondo (279)
- # cljdoc (16)
- # cljs-dev (15)
- # cljsrn (7)
- # clojure (168)
- # clojure-europe (36)
- # clojure-nl (10)
- # clojure-spec (6)
- # clojure-uk (5)
- # clojured (1)
- # clojurescript (20)
- # core-async (16)
- # crypto (2)
- # cursive (13)
- # datomic (25)
- # events (7)
- # fulcro (21)
- # google-cloud (3)
- # graalvm (2)
- # graalvm-mobile (2)
- # gratitude (3)
- # helix (20)
- # honeysql (4)
- # hugsql (15)
- # introduce-yourself (15)
- # leiningen (2)
- # lsp (24)
- # luminus (22)
- # malli (21)
- # meander (11)
- # midje (1)
- # other-languages (1)
- # pathom (8)
- # re-frame (5)
- # reagent (5)
- # releases (2)
- # reveal (1)
- # shadow-cljs (18)
- # spacemacs (17)
- # sql (9)
- # tools-build (12)
- # tools-deps (4)
- # vim (12)
inspired by Clojure's new iteration
fn, I've been thinking through consuming paginated APIs in ClojureScript, and came up with this as an idea: https://github.com/lilactown/async-seq
here's a simple example https://github.com/lilactown/async-seq/blob/main/dev/user.cljs#L28-L39
the idea is a seq
-like abstraction that represent sequential async processes, allowing transformations of them just like seqs
I want to use bundle
target with webpack, and target to node
.
My code depends on a library which requires fs
in its namespace, like this
(ns macchiato.fs
(:refer-clojure :exclude [exists?])
(:require ["fs" :as fs]))
When compile with cljs.main
, it said
No such namespace: fs, could not locate fs.cljs, fs.cljc, or JavaScript source providing "fs" in file /home/tianshu/.cljs/.aot_cache/1.10.914/A5608AE/macchiato/fs.cljs
But I think fs
is builtin for node. What happened here and how can I make it to work?@doglooksgood Hrm. If you just do (require 'fs)
at a Node REPL, you generally get access to the fs
builtin
Hunch is that you need to specify the node target in order to make this work... (this has been a while for me)
I think I just made it work. I don't have to use bundle
target, node
target works well for my case.
Does the arity of macros behave differently in cljs than it does in clj? I tried to define a macro with a [s]
overload and a [s & ss]
overload (typical pattern where the latter just invokes the former in a loop), and when I tried to invoke it with multiple arguments, I got an error saying Wrong number of args (1)
. Best I can figure is that it successfully expanded the 1+n-ary overload, which then invokes the 1-ary overload, and it complained because the 1-ary overload got clobbered or something.
(defmacro my-macro
([s]
;; proprietary stuff here, seems to work fine)
([s & ss]
(for [s2 (cons s ss)]
(my-macro s))))
I suppose I might be blundering my reasoning about compilation steps somewhere in that second overload...
It won't work on CLJ either. A nice explanation: https://stackoverflow.com/a/25569059/564509
Oh right okay. What I attempted to write amounts to attempting to evaluate the first overload while the second is still expanding. If it ran, it would execute the for loop immediately, yielding a lazy sequence as the "syntax". Which clearly isn't right. I need to yield the code that will invoke the first overload, so that it expands on the next pass. Is that right?
Ah, and the reason it blew up instead of doing that wrong thing is that it lacks those hidden arguments.
I'm mildly curious why it can't insert those arguments in this context the way it would in other contexts, but the answer to that probably involves a deeper dive into macro internals than I want to wrap my head around right now 😆
Happen to know any good resources that elaborate on this bit? Feels like a good idea to familiarize myself with other macro pitfalls before I learn about them the hard way, and while I can see an intuitive sense to this I struggle to see the concrete reasons. > Instead, consider a helper function to do most of the work on behalf of the macro. Indeed, this is often a good practice for other macros as well.
Mm, not really sure why that would be a good practice for regular macros. clojure.core
itself doesn't use that approach.
Off the top of my head, I know only of one other pitfall that's not immediately obvious with its fix - if you need your macro to generate code with specific symbols, you have to quote-unquote them. So e.g. to end up with just a
after macro expansion, you'll have to use ~'a
within a syntax quote.