Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gensym / anonymous function syntax breaks fast refresh #117

Open
SevereOverfl0w opened this issue Dec 18, 2022 · 2 comments
Open

gensym / anonymous function syntax breaks fast refresh #117

SevereOverfl0w opened this issue Dec 18, 2022 · 2 comments

Comments

@SevereOverfl0w
Copy link
Contributor

Simple reproduction that will cause fast refresh to always do a full reload:

(defnc ...
  (hooks/use-effect
    []
    (run-my-callback #(identity %)))
  ...)

It will be fixed by using (fn [%] (identity %)) instead. The problem is that on each reload the gensym'd binding that replaces % is changed. Compare:

(hooks/use-effect [] (reitit.frontend.easy/start! (reitit.frontend/router []) (fn* [p1__27869#] (identity p1__27869#)) {:use-fragment false})) 
;; vs
(hooks/use-effect [] (reitit.frontend.easy/start! (reitit.frontend/router []) identity {:use-fragment false}))

I don't have an clear idea on how to best fix this. If there was a way to detect & remove gensym'd symbols, that would be ideal. I don't know think that's possible at all.

The anonymous function syntax seems likely to be the most common (only? is this something that can only happen from syntax, or could a macro cause it too?) cause of this and it will always end its binding with #, or you could pick up on the prefix of p\d+__ for that case, too.

@lilactown
Copy link
Owner

Thanks for the report.

I haven't tested this, but since it's the defnc macro that does the fast-refresh detection, I think this is only a problem for things that gensym new bindings in the reader. E.g. if you have a macro that gensyms some binding,

(defnc my-component
  []
  (hooks/use-effect [] (my-thing-that-generates-some-bindings-internally))
  ,,,)

The code used by defnc will be the non-macro-expanded forms. It's only because the anonymous function syntax expansion happens in the reader that this is a problem. I think.

Based on my reading here https://github.com/clojure/tools.reader/blob/fb185af411fa379e48e5d0a9e623b68f552d8c92/src/main/clojure/clojure/tools/reader.clj#L528-L532 I think that detecting the # at the end of the binding seems easiest.

PR welcome!

@roman01la
Copy link

roman01la commented Oct 3, 2023

FYI I had a similar issue in UIx, here's the fix, perhaps it can help pitch-io/uix@7c39a4e

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants