This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # aws-lambda (6)
- # beginners (38)
- # boot (39)
- # cider (44)
- # cljs-dev (9)
- # cljsrn (96)
- # clojure (142)
- # clojure-dev (6)
- # clojure-dusseldorf (8)
- # clojure-greece (45)
- # clojure-ireland (3)
- # clojure-italy (7)
- # clojure-norway (6)
- # clojure-russia (26)
- # clojure-sg (16)
- # clojure-spec (31)
- # clojure-uk (39)
- # clojurescript (125)
- # cursive (38)
- # datascript (4)
- # datomic (18)
- # emacs (34)
- # figwheel (2)
- # hoplon (3)
- # immutant (23)
- # jobs (1)
- # lambdaisland (2)
- # lumo (13)
- # off-topic (77)
- # om (8)
- # onyx (9)
- # pedestal (2)
- # play-clj (1)
- # re-frame (52)
- # reagent (3)
- # rum (4)
- # spacemacs (2)
- # specter (4)
- # unrepl (37)
- # untangled (8)
- # vim (79)
- # yada (1)
@ingvij Did you mean using a macro to generate the functions from the stored metadata?
I'm interested in knowing how that will prevent bugs due to API changes mostly. That's one reason I liked letting the generated versions live side-by-side.
Not actually prevent bugs.. AFAIK, neovim API versioning won't break as API version bumps.. Actually, this will make simpler (by auto-generating the functions) to bump as neovim bumps their API.
If we have static definitions of each function, we're entitled to keep them as the API evolves
Right, rather than adding the generated source, you'd only have to add the metadata resource, in that case.
Right, you could just have a macro which generates them all using the stored data + api level. I was a little torn between macro + stored metadata vs generated code myself. I see pros and cons to both.
Macro should work right? By the time dependent code is evaluated, that macro should have expanded to create whatever namespaces and functions it needs.
Maybe that was my problem with it -- that central macro has to be included in your code somewhere, else it won't even compile.
The thing with keeping the generated code is, as soon the API evolves, we're growing the codebase with code we can't actually touch. After a few bumps, we'll have several files full of static content making it very hard to track things down..
Not only that, there will be several functions left there we won't ever be able to remove and we'll have to be careful about changing the underlaying code..
How would using a macro to generate everything based on the stored metadata solve that? Wouldn't that stored metadata be just as off limits as the generated code?
FWIW, I'm not being deliberately obtuse here -- and normally wouldn't want to generate code, and fought doing it. Just trying to wrap my head around this all.
We don't need to use a macro.. We can delay the function generation to happen right after connecting on neovim. Since we just negotiated the API version to use, we can generate the functions from there.. Not the best approach, but it's a macro alternative.
Say you're writing a plugin. When you eval your plugin code, it will complain that namespaces and functions don't exist (unless you've interned all of that stuff already).
So you're dependent on the existence of the connection -- believe me, I wanted it to work that way, and coded it that way originally.
What if we have a looser structure, such as
(nvim/api "nvim_get_var" "g:my_var"), not having a static implementation of it?
When I got to that point my interpretation was that would not be entirely consistent w/ the goals of the Noevim API client stuff.
They provide this metadata complete w/ types, I'd assume, because they want first class objects, functions, methods, whatever
The real thing for me is not having a static snapshot of the API, since it will be different for every bump on their side..
I agree, I'd rather not as well. I just don't see a way around it that allows you to evaluate your plugin code w/o some ceremony.
And to get around that, my solution was static snapshots per API level -- because according to what I read, that should be non-breaking.
I've thought / written so much about this in trying to make these decisions solo last year.
Glad to finally have a chance to air it out. The static generated code bugs the shit out of me.
So let's say you're in your editor and you're building a plugin. And you write some code to require a namespace. How do you ensure that macro is evaluated somewhere before that require happens?
That's sort of the crux of it for me, I think. The only way I could see was to tell a dev in the docs "You have to require neovim-client.core, and put (generate api-level) somewhere in your code". And that just felt weird. As much as I hate it, it felt more weird than generating the code statically.
> How do you ensure that macro is evaluated somewhere before that require happens? Is it too absurd to use a lein/boot plugin? (legitimate question)
I can totally see how people would prefer that to a bunch of stored generated code.
I just use it for the classpath these days, and that's it. I honestly haven't used Boot.
This is probably my last
good idea... What if we expose a command (on neovim) or a function that generates all those functions for the supplied API level and we leave that on the plugin side?
I mean, it is still generated code that will statically live on a repository, but we don't need to keep all possible versions on our side... Instead, the plugin author decides on which version to support and when to bump...
This is a one-time command/function to run and we expose this functionality while we don't pollute our codebase...
I'm kind of torn -- think I need to sleep on that one. It's ceremony, but it'd be easy to document and straightforward. And I think it's something plugin developers would tolerate.
That's definitely my favorite alternative so far. For a general purpose library that you just grab from clojars and use I probably wouldn't like it, but this thing is super niche. I think at the point where you're building Neovim plugins in Clojure, maybe you won't get too turned off by having to run one command line before diving in.
> For a general purpose library that you just grab from clojars and use I probably wouldn't like it, but this thing is super niche. I totally agree
I'll try to think of another alternatives, but this seems a good enough approach without resorting to lein plugins, injected macros or black magic..
I think -- not sure, but looking -- that there are some other niche libraries that do something similar in the Clojure ecosystem.
I'm liking it, but would like to give it a little hammock time. One last plug for storing all of the generated code: it's actually decent documentation of what's changed between API levels. Also, while it is sort of ugly, it's more or less benign. API levels change very infrequently (supposedly). Specifically, we've only gotten 0, 1 & 2 over the last few years. It would be different if we were generating side-by-side versions of client code for every AWS service, for example.
I guess these are also arguments in favor of making the developer perform a one-time generation as well. It's pretty darn close to the same thing.
anywho, thanks for brainstorming. I hadn't even considered that last alternative, but I'm liking it. Back in a bit.