To accomplish what?
You need to start with a concrete use case as that resolves many design questions: Should the produced code use the CLR's GC? Is it allowed to use unsafe instructions? How to interface with CLR's "interface" or "virtual" calls? How to bridge between Nim's UTF-8/byte strings and CLR's UTF-16?
Fwiw you can compile Nim to a DLL that you call from C#.
you can compile Nim to a DLL that you call from C#
Nobody going to do that.
By adding DLL you add tons of complexity to CLI/JVM project. Most CLI/JVM developers are not familiar with that and you make work hard for them. If it crashes - it's way more complicated to figure out why. If you use perf tooling or tune GC in CLI/JVM - how you can't use it also for DLL. If you deploy, on different platforms - you need to figure out how to supply DLL in your build chain and if it has some specific requirements or dependencies on some platforms. And so on and on.
I created a DLL using C++ and called it from C# long time ago. C# can call C functions in DLL using marshall. If I remember correctly, C++ DLL exported some C functions, like createObj func create a C++ object and return a pointer to it, freeObj takes the pointer and free the object and other functions that takes that pointer and do something. In C# code, manage returned pointer manually. I also wrote function signatures of exported functions in C# code using marshall that is similar to Nim's importc. I didn't got much problems (if I remember correctly) and it worked.
You probably be able to do similar thing with Nim. DLL written in Nim export C functions using exportc and dynlib pragma. createNimObj proc create a ref object, increase ref count of it with GC_ref and return to C# code. freeNimObj takes that pointer, decrease ref count with GC_unref. And other Nim procedures that takes the pointer and do something with the given ref object. You probably need to manage the pointer returned from createNimObj manually unless C# has something like destructor. I didn't used C# for long time.
I doubt it's a good approach, mixing two runtimes, more bugs and problems, especially when you don't control environment when it's on many servers or distributed as app on different platforms.
You should always give advice about the things you didn't even try...
i would assume a CLR target would do everything as the CLR does it. So yes it would use the system GC (equivalent to gc:none as far as the compiler is concerned.)
Unsafe doesn't mean anything to the CLR. That is a C# keyword that just allows pointer stuff, while in CIL (the bytecode) you just have ops that deal with managed and unmanaged pointers. No special handling by the language needed.
Strings I would assume to be ultimately backed by System.String with a thin layer to sugar coat it to match the stdlib. AFAIK we already do that for JavaScript and this is more or less what the .NET languages all do.
Interfaces and objects might need a couple pragmas. We already have method which does largely what virtual calls do on the CLR. I would be inclined to say interface attachment to objects would also be a pragma. We have concepts now (though I haven't used them yet) but I couldn't say how easily those could be mapped. I don't think we have syntax to say "this object should comply with this concept" because if we did then we could very likely just piggyback on that (with the concept having a pragma to indicate it means an interface, CLR-wise.)
Still working on a research project tangential to this. (But more on that when its over.)
Still working on a research project tangential to this. (But more on that when its over.)
Are you aware of NIR?
Is NIR this RFC? https://github.com/nim-lang/RFCs/issues/516
Seems like exciting work. What state is it currently in? It would be great for the community to see the state of progress here, e.g. on github as a milestone or checklist on the RFC (does this exist somewhere already?).
I assume you're holding back on this communication until the MVP is complete?
I assume you're holding back on this communication until the MVP is complete?
Yeah... :-)
You may also want to look at the mechanisms in the compiler for member, virtual and constructor see https://nim-lang.github.io/Nim/manual_experimental.html#virtual-pragma
They should translate pretty well to C#, especially member and virtual. Interfacing with generics can be more painful but C++ paved the way https://nim-lang.org/docs/manual.html#importcpp-pragma-importcpp-for-procs
For other things you can go pretty far without modifying the compiler with macros and the emit pragma https://nim-lang.org/docs/manual.html#implementation-specific-pragmas-emit-pragma
At the time I asked I was working on a CLR runtime and looking at a project that used it heavily. I'm no longer associated with any of that. :woozy:
It seems like whatever good the CLR could have been used for time is now better spent on the JVM or WASM.