Nim compiles to JS both directly, and indirectly (emscripten) with various trade-offs (e.g. 64 bit ints require emscripten)
Kotlin can also compile to js directly and can autogenerate typescript definitions for the generated code.
It also compiles to C, C++ and Objective C giving you the simplest most efficient FFI to those languages one can hope for (including e.g. exception handling) while at the same time addressing the largest set of platforms (got a C compiler? you can use Nim).
Wow, nim has implemented that much transpilers?
This is kinda impressive but I would rather want a language that compile to Binary instead of compiling to another language, AND that offer nice FFI interop
Kotlin has state of the art language interop through graalvm but here it does not qualify as native.
For native interop it can be done but is subpar. But openjdk is working on a new API luckily.
Metaprogramming
Interesting topic for sure!
I've never learnt a LISP.
I did use macros when I was doing C/C++ and honestly I don't get their advantages vs
@Decorators() (pre compile time codegen)
and they have a reputation of breaking IDEs
Kotlin like Java can generate code/classes at runtime and has full support for reflection.
Tangeant: Kotlin can mark any function as in/postfix which allows to easily create DSLs.
Due to this Kotlin community has created a lot of elegant, declarative DSLs such as for testing.
Nim's async support (comparable to Python and C#) is a user-level library.
Kotlinx.coroutines is the official library the language simply has to expose the keyword suspend.
So is, for example, pattern matching. Can Kotlin do that?
Kotlin has some pattern matching features in its when keyword,but no it cannot currently destructure in when.
But the subject is active and it should come in a following release, especially since Java is getting pattern matching.
https://github.com/Kotlin/KEEP/pull/213
But if your point was that macros allows to modify the abstract syntax tree,
Kotlin compiler plugin API offer much more power (you can modify anything anytime (the AST, the IR, the bytecode)
It is arguably far harder to use than powerful macro but it does not prevent experimented guys from scalaifying Kotlin through https://github.com/arrow-kt/arrow-meta/issues
They are bringing for example union types as an unofficial extension to the language.
They could bring pattern matching earlier in theory.
Size: Nim compilation through C produces standalone and (relatively) tiny executables; it matters for embedded platforms. How does Kotlin fair in this respect?*
I'm afraid kotlin is not made for such a use case but today even embedded platforms should have a few dozens of free MBs