I recently converted some Nim ORM code to TypeScript and was surprised how similar the source code looks like. If you ignore visual differences of OOP vs Multi-Dispatch, and think at how it actually works, it's almost identical.
I think it's possible to integrate Nim with JavaScript/TypeScript that generated JS code would be almost identical to Nim code. With method overload and multi-methods. And being small, idiomatic JS and human-readable.
JavaScript runtime has capabilities similar to Nim, with types, mutli methods, metaprogramming. JavaScript is not what it looks like, at it's core it is a Lisp that on surface looks like and used as Java. The problem is that those Lisp cap capabilities are inconvenient to use, but when you generate the code, such inconveniencies doesn't matter.
Example, method overload:
proc add[T](list: seq[T], v: T): void = list.add v
proc add[T](set: HashSet[T], v: T): void = set.add v
proc add[T](col: MyCollection[T], v: T): void = collection.add v
in JS/TS, nobody writes such JS code manually, but it's possible to generate it in this way. (It's also possible to handle arg name overload in simlar way, although I think it would better to not support it).
function add<T>(array: T[], v: T): void
function add<T>(set: Set<T>, v: T): void
function add<T>(col: MyCollection<T>, v: T): void
function add<T>(o: any, v: T): void {
if (o instanceof Set) o.add(v)
else if (Array.isArray(o)) o.push(v)
else if (o instanceof MyCollection) o.add(v)
else throw new Error("internal error")
}
Even better, although harder to implement, it should be possible to map Nim multi-dispatch into idiomatic JS OOP code. And generate the following code as MyCollection class and extension method for built-in JS Array and Set. That would be almost the same JS code as if written by human.
class MyCollection<T> {
function add(v: T): void { this.add(v) }
}
function add<T>(array: T[], v: T): void
function add<T>(set: Set<T>, v: T): void
function add<T>(o: any, v: T): void {
if (o instanceof Set) o.add(v)
else if (Array.isArray(o)) o.push(v)
else throw new Error("internal error")
}
col.add(1) // emulate multi-methods
add(array)
add(set)
You can export variables the same way as functions. JavaScript doesn't have custom types, so exporting a type doesn't really make sense.
JS does have types, can use it in different ways and has powerfull metaprogramming capabilities.
class User {}
console.log(new User() instanceof User)
For a start, the Nim source has valuable type information, the generated JS loses this information.
Even JS has some type information. As there's also TypeScript.
Why wouldn't someone just use TypeScript then? Nim's targeting the lowest common denominator which is ES3 I believe. I don't want my compiler to produce human readable code, I want it to produce optimized code with as small of a runtime footprint as possible.
Nim can already be promoted for corporate environments - you just need to sell it correctly (which is difficult - but your solution doesn't make it any easier). Nim producing JS that isn't friendly to the eyes isn't the reason most companies choose to forego Nim (if they've even heard of it). The reason most companies forego Nim is because of the lack of a talent pool to hire from.
Honestly, I'd like to see less time invested in Nim's JS backend and more time invested in Nim's WASM / LLVM story. I think the JS backend is fine as it is - Nim doesn't need a TypeScript backend.
Why wouldn't someone just use TypeScript then?
Because it doesn't have extension methods and method overload :)