From Andrey to ~technomancy/fennel
>Well, have you taken a look at fennel-ls? If you compare the quality of >the static analysis from fennel-ls vs the Clojure language server, the >Fennel one is dramatically better despite being much less code. This is >only possible because it can do static analysis on the expanded code, >whereas the Clojure just gives up at the first sight of a 3rd-party macro. I wonder if this is because Fennel compiler is much easier to embed and use? I haven't seen any public statements that clojure-lsp doesn't expand macros due to security concerns. I suppose, Clojure macros are way harder to expand if done manually, and it was too hard or cumbersome to rmbed the whole compiler for this sole job. Anyhow, I think clojure-lsp solution to this is fine, and fennel-ls solution is also fine. >> In fenneldoc I do the sandboxing mainly so the scripts to minimize
From Andrey to ~technomancy/fennel
>Sorry, I don't think this is easy! This sounds really difficult, because >"what's in the module" will frequently depend on modules which will not load >in the compiler sandbox. Honestly, I never fully understood why we do sandboxing of the compiler in the first place. It, however, limits interesting things that can be done with macros, like conditional based on environment variable for example. In fenneldoc I do the sandboxing mainly so the scripts to minimize effects, but a lot of libraries may need to escape sandbox to test the documentation, so I provide a setting for that. Though I think I'll drop the sandboxing in future release entirely. >> ```fennel >> (fn public-foo [] :ok)
From Andrey to ~technomancy/fennel
On September 6, 2023 4:49:45 AM GMT+03:00, Mike Mogenson <michael.mogenson@gmail.com> wrote: >Thanks. I didn't know Lua compares tables by hash instead of value. >Now Fennel's behavior makes sense. > >I wonder if it would be possible to construct a new list or table >within a match branch. Unfortunately the following example does not >work: > >(let [pattern [1]] > (match [1] > [(unpack pattern)] :matched-unpacked-list > _ :no-match)) ;; -> Compile error: can't nest multi-value destructuring Do not forget that match is a macro, and macros don't know anything about
From Andrey to ~technomancy/fennel
>;; case 1 >(let [pattern 1] > (match 1 > pattern :matched-var > _ :no-match)) ;; -> matched-var Here, the compiled code is just a check that 1 is equal to a value of the variable named pattern >;; case 2 >(let [pattern 1] > (match [1] > [pattern] :matched-var-in-list
From Andrey to ~technomancy/fennel
>I would be fine adding the module or at least the module name to this >table if you still need it. Is it still needed or did you get this taken >care of? Yes, I think it's done now. The protocol can be configured properly during initialization, and we still need the variable in emacs for completion to work, so everything is fine now. -- Andrey Listopadov
From Andrey Listopadov to ~technomancy/fennel
I've been tinkering with my libraries for the last week or so, porting them to the single file approach, where both macros and functions are exported from the same file with a small eval-compiler and macro-loaded hack. For what it's worth it works fairly well, allowing me to distribute my libraries easier than before. And once again it got me thinking how we can make macros more like macros in other lisps. We've discussed in the past the ability to export macros from the same file with some new special, and while I think this approach might work there's one other elephant in the room - macros using other macros *and* functions from the same module. Consider: ``` fennel
From Andrey Listopadov to ~technomancy/fennel
Andrey Listopadov <andreyorst@gmail.com> writes: > After a bit more fiddling, I rewrote my testing library to be a > single-file module, and I'm happy to say that the trick works both for > regular modules, and for init.fnl modules, which means that it is more > general than the relative-require stuff I was going for originally to > have a similar setup. I've also ported few other libraries to this style: async.fnl[1], lazy-seq[2] and finally cljlib[3]. All of these, can now be required to get functions, and the same module can then be required to get macros: (local clj (require :cljlib))
From Andrey to ~technomancy/fennel
>Ah that makes sense, no worries and thanks for clarifying.
Maybe you can suggest a better wording? English isn't my first language, and I'm not all that familiar with customize docs
--
Andrey Listopadov
From Andrey to ~technomancy/fennel
>One small note to share: in the docstring of >`fennel-proto-repl-fennel-module-name` it says that there’s no need >to include quotes in module name, but I found that I did need quotes. >For example: > >┌──── >│ ((fennel-mode . ((fennel-proto-repl-fennel-module-name . lib\.fennel)))) >└──── What I meant is that you need to write "lib.fennel", not "\"lib.fennel\"". It mostly applies to the customize interface, as it doesn't show quotes for string values. So the correct code is just: ((fennel-mode . ((fennel-proto-repl-fennel-module-name . "lib.fennel"))))
From Andrey Listopadov to ~technomancy/fennel
Christian Packard <christian@cpacklabs.com> writes: > I can see the benefits of a standard solution. Armed with the knowledge > above I’d be fine using the configured path and discarding this patch. > > What originally prompted me to submit it is that there wasn’t an indication > that the misconfigured path was the issue. Even when setting > `fennel-proto-repl-log-communication` to `t` and > `fennel-proto-repl-kill-process-buffers` to `nil` the only message I had was > `fennel-proto-repl--start-server: Unable to initialize Fennel Proto REPL: timeout`; > no other debug info or buffers were available. > > Is there a sanity-test function or other documentation I can add so future