-
Notifications
You must be signed in to change notification settings - Fork 11
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
Macro file is required multiple times during compilation #38
Comments
This is by design f9a4c29 so hotpot can track if a module needs recompilation due to a macro file changing. If the macro is only loaded once, only the first file to use it is able to "mark" the macro file as a dependency because all other requires won't hit the searcher. I have been meaning to look into adding a compiler event to Fennel itself that would let hotpot get notified when a macro is required (maybe? via a compiler plugin) but haven't had the time to look or discuss if that patch would be accepted or check if it would even solve the issue. I agree that this does break the "just fennel" rule, but it's needed to make hotpot work otherwise you'd have to manually compile/touch anything that Can you get around your issue by adding a "has-init'd" guard? (if (not _G.__core_counter)
(set _G.__core_counter 0)) Also care, the counter may not behave like you expect since Hotpots code is compiled as needed when something is changed, not in one monolithic set as when you test it in Fennel.
I had the same issues with #6 using gensym which basically does what you're doing probably (autoincrementing names) but because of the cross/inter compile cycle I had to use a timestamp, though there are probably more elegant ways. Since it's only run at compile time and you're already throwing speed out you could probably just checksum the incoming list or something for a real uid. So in real world usage of Hotpot, assuming you don't nuke the cache every time you make a change, it's more like this, with multiple compile passes:
Annoying, I know! |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Ah, what a pain.
Sadly, no. It was one of the first workarounds I tested, the if is always true because the value is not saved between imports of the macro file.
One of the workarounds I tried was using that timestamp trick, but, because Lua only uses seconds as the timestamp, the identifiers are still repeated. The workaround that I am currently using is generating a uuid as an identifier, seeding the randomness with the current timestamp. It still doesn't work sometimes, so I think I will have to generate a checksum based on the arguments or something. Sadly this bug breaks my macros related to mappings, autocmds, commands, or anything that requires a generated identifier for a global Lua variable. What a pain. Can't you create an option for just "running 🥲 |
Hmm, that sounds like part of Fennels sandboxing. Hotpot wont intentionally unset anything but I would bet the Actually I bet it's a bug in Fennel that hasn't made a release yet, which actually popped up because I was running into a related issue bakpakin/Fennel#381, bakpakin/Fennel@e461e24 Disable compiler env sandbox and add the guard: diff --git a/config/fnl/core/macros.fnl b/config/fnl/core/macros.fnl
index 7cb1171..282fcc2 100644
--- a/config/fnl/core/macros.fnl
+++ b/config/fnl/core/macros.fnl
@@ -6,7 +6,9 @@
;; module.
(print "The macros.fnl file was required.")
-(set _G.__core_counter 0)
+(print _G.__core_counter)
+(if (not _G.__core_counter)
+ (set _G.__core_counter 0))
(fn display-counter [name]
"This is a small macro that displays the counter current value."
diff --git a/config/init.lua b/config/init.lua
index 55ae790..866ac7e 100644
--- a/config/init.lua
+++ b/config/init.lua
@@ -7,5 +7,13 @@ if vim.fn.empty(vim.fn.glob(hotpot_path)) > 0 then
})
end
-require("hotpot").setup()
+require("hotpot").setup({
+ compiler = {
+ macros = {
+ env = "_COMPILER",
+ compilerEnv = _G,
+ allowedGlobals = false,
+ }
+ }
+})
require("core") Replace You have to do this because the latest stable fennel release doesn't actually pass the compiler options correctly. Profit.
No not really... That's basically just disabling hotpot. |
For what it's worth, I hit similar pains with macros and how Fennel expects you to behave when using them. Hotpot will only track the latest stable, but because of this, it will only change that file very rarely. If you fork Hotpot and do your HEAD patch to I would like to not need the patch, but yeah, haven't gotten to trying to upstream a solution yet. |
At the end I followed your idea and implemented my unique symbol generator using checksum, specifically kikito/md5.lua. Here is the implementation, it works like a charm (but it's not foolproof, if two function definitions are identical it can break): (macro gensym [...]
(local {:sumhexa md5} (require :md5))
(->> (icollect [_ expr (ipairs [...])]
(tostring expr))
(string.concat)
(md5)
(string.format "__%s")
(sym))) Ideally I would have used (local {: view} (require :fennel)) It says that Can you test it on your side? This only happens when inside a macro. I can open an issue if you need to, with a reproduction using Docker. |
Isn't that the idea behind hashing them? 😄 Not sure if that's an edited paste or not, but you might want to use a different name since Seems to works fine for me, have you got |
Yes 😆, but if the functions access different values with the same symbol, they would be considered equal, which would create problems. e.g. ;;; File1
(let [x 10] (gensym #(+ x 10)))
;;; File 2
(let [x 20] (gensym #(+ x 10)))
I am using
Yes.
I cannot reproduce it at this moment, it seems to be irregular behaviour, when I get to reproduce it again I will open an issue. |
I could reproduce it on my Neovim configuration but not on Docker. When using it on my vim configuration macro: Click to see the result of
|
Hm, yeah I tried pretty hard to recreate it. When testing in docker you have to run nvim twice because the first time Fennel is loaded to compile hotpot itself and your config, the second time Fennel isn't loaded until you specifically require it. Note: the examples here are done with In this video:
edit: streamable link if GH wont serve video https://streamable.com/a2ib57 fennel-req-2021-09-26_15.55.31.mp4In this video:
fennel-req2-2021-09-26_15.57.36.mp4So I think it must be something in your config that's fiddling with something? Maybe cljlib is doing something unexpected? |
In fact it's even stranger that it only doesn't work in macros for you since being in a macro implies that Fennel must have been loaded already - to compile the macro. It may be another sandbox issue perhaps, but my tests in Docker (in and out of a macro file) worked fine with just the default Hotpot options save for |
Maybe related to the patches for using I will do more testing tomorrow, thanks for your help! |
Btw, even stranger is that it's not available when evaluating a macro with conjure (using the |
Might be related to #1 in some way, I haven't re-looked into whether that conjure patch is out. Also make sure aniseed isn't doing anything too if you've got that in nvims path. (I have conjure installed, so it existing isn't an issue. I don't have aniseed installed.) If Probably worth opening a separate issue if you can track a reproduction down. I will leave this issue open until the hook gets merged/rejected. |
Lot of stuff got in the way but this is probably fixed now since we now use a compiler plugin to track dependencies, so macros should only get compiled once and required as normal. |
Great, sorry it took forever to get around to it. |
Hello!
This issue was kind of a pain to debug.
One of the functionalities that I make use of in my macros to configure Neovim is that a global inside a macro file is defined when the macro file is required and then can be used by any macro during the compilation.
An example of a use of this is a global counter:
This counter can be used in the macros inside the file to generate an unique symbol each time without needing to use
(os.date %s)
or the like.This functionality is present in the normal Fennel behaviour as can be seen in the reproduction repo.
In hotpot the macro file is evaluated each time it is required, which by itself goes against the normal behaviour of Fennel, but it seems that the counter is reset in each evaluation of the macro file, as if it wasn't set.
How to reproduce the issue
I created datwaft/hotpot-issue_38 to reproduce the issue using Docker.
Expected results
This can be seen by executing the following commands inside the Docker container:
As you can see the
macros.fnl
file is only required once and the counter is maintained between files.Current results
As you can see the
macros.fnl
file is required once per file and the counter is not maintained.The text was updated successfully, but these errors were encountered: