Hey,
I thought about making a nim plugin host for neovim. Basically: Compile all nim plugins into one binary, add some boilerplate for vim side stuff that can be called via msgpack-rpc and give some api things.
Anyway, I am still mildly traumatized because cutting the intermediate representation during json parsing cut the run time of some small program from minutes to under a second. So I wondered if adding basic types directly to a byte array during sending instead of wrapping first could improve performance significantly. I run into some problems so I figured I might as well look at the echo signature to see how it handles things.
Weirdly enough, neither
proc foo(x: varargs[stmt, `$`]) = discard
nor
proc bar(x: varargs[untyped, `$`]) = discard
compile.
Any ideas? Is that something that depends on compiler magic and isn't allowed elsewhere?
Can't you use this?
proc bar(x: varargs[string, `$`]) =
for s in x:
echo s
That... Actually makes a lot more sense. Oh, any idea what the best way to do this would be?
type Encodable* = concept x
encode(x) is Encoded
proc test(x: varargs[Encodable]) =
for item in x:
discard encode(item)
I was under the impression that it would instantiate test for each method signature that is used?
It would be more like this:
proc test(x: varargs[Encoded, encode]) =
for item in x:
discard item
Afaik you can't have a generics "varargs".
@Tarmean
You can have a varargs[] of typed/untyped, but only in a macro, eg:
macro test(args: varargs[typed]): typed =
for a in args:
echo treeRepr(a)
test(1, 2.0, "Three") # prints...
# IntLit 1
# Float64Lit 2.0
# StrLit Three
Thanks for your responses! Turns out the nvim --api-info output got borked when piped on windows and both set-clipboard in powershell and echo in vim stopped on the first nul byte. Which seems weird because neither language uses nul delimited strings. Took me a while until I had the idea to import fwrite amd before that I was just hopelessly trying stuff while nothing worked.
Anyway, I had a small problem because nim can't just throw everything into a dictionary and I didn't feel like writing a case block for each type. The macro to automate thatis really simple, though, so I just threw it into a generic method and use that. I feel like that is preferable to runtime type inspection? Or is there some other way?
Also, completely different topic: Asyncdispatch works well but I think it has to run single threaded? That would mean that running multiple plugins in the same host could just block all but one if that one doesn't await, right?
Any ideas if it would be preferable to let plugins use threads for long running tasks and communicate over channels or to use a threadpool and handle the async part differently?
Edit: last thing, I swear! The net module still doesn't seem to handle unix sockets? Seems like a fairly important feature to me. Don't want to be completely site tracked, though, does anyone know how much is still missing?
Yet another edit: Turns out I am horrible with macros. Why does this fail?
macro c1(): untyped =
discard
template debugMacro(name: untyped): untyped =
macro `debug name`():untyped {.gensym.}=
echo treeRepr getAst name()
discard `debug name`()
debugMacro c1 # NilLit nil
macro c2(a: untyped): untyped = a
template debugMacro2(name, arg: untyped): untyped =
macro `debug name`():untyped {.gensym.}=
echo treeRepr getAst name(arg)
discard `debug name`()
debugMacro2 c2, "a" #StrLit a
macro c3(a: varargs[untyped]): untyped = a
template debugMacro3(name: untyped, arg: varargs[untyped]): untyped =
macro `debug name`():untyped {.gensym.}=
echo treeRepr getAst name(arg)
discard `debug name`()
debugMacro3 c3, "a" # Bracket
# StrLit a
debugMacro3 c1
# Error: internal error: (filename: compiler/vmgen.nim, line: 500)
# No stack traceback available
# To create a stacktrace, rerun compilation with ./koch temp c <file>