SoFunction
Updated on 2025-03-04

TypeScript Nim Alternating Use Details Analysis

Some thoughts about using TypeScript and Nim alternately

My previous background was mainly js and ClojureScript, and I had a limited understanding of types. I only started using statically typed languages ​​for a long time by Nim. TypeScript is just like type checker.

Nim's obvious problem

JavaScript was made by Google, and the debugging experience is really good.

As for Nim, most of the errors can be located by type information, but there is no handy breakpoint debugging tool, and it often depends on a large number of logs, so I can't dig deep enough.

I have also used Profiler. What exports the call stack and overhead ratio of text, of course it is not as clear as Chrome DevTools.

The user experience of VS Code is naturally far from comparable to TypeScript, so I just sublime.

Nim's echo first gave me a headache. It was quite annoying that there was no automatic space addition.

Nim does not have a built-in string interpolation, fmt is not sure whether it is a function or a macro.

Usuallyfmt"balbla {b}"Such syntax can be interpolated, but the effect is not as convenient as language-level interpolation. If there is a writing method,{or}It also needs to be processed manually, and I feel bad when I use it.

It will not be so troublesome to implement interpolation, JavaScript or CoffeeScript in the language.

Nim type and runtime consistency

Although TypeScript has a very coquettish type system, I didn't use strict, and not all dependencies are ts.

Then occasionally I will encounter the type I wrote but it is not the case below, which is inexplicable.

Nim's type corresponds directly to data. Except for some edge cases, it can be used, which means that the errors reported by type checking are fixed, and the errors corresponding to the code are solved, which makes me feel that the types are reliable. Of course, this should be like this in many static languages.

Method call syntax

Nim is not an object-oriented language, and the object inside roughly corresponds to the struct of C, not an object.

The object is data, which is quite accustomed to.

However, in terms of code view, Nim is still a bit close to js that supports OOP writing. I mean a lot of it(c)The syntax of this method call is called Method call syntax in Nim.

I just knew that this was already in D, and the wiki clearly stated:

/wiki...

The Nim code corresponding to this feature looks like this:

type Vector = tuple[x, y: int]
proc add(a, b: Vector): Vector =
  ( + ,  + )
let
  v1 = (x: -1, y: 4)
  v2 = (x: 5, y: -2)
  v3 = add(v1, v2)
  v4 = (v2)
  v5 = (v2).add(v1)

I didn't care about it when I first used it, but I felt it flexible as I migrated some code to ts.

In JavaScript, inheritance, polymorphism, and depend on class structure to achieve it, which also means that I need to define class, then new instance, and then use it.

But defining class means that this data is not as straightforward as JSON.

I don't use OOP much, but after thinking about it, it is already very powerful to achieve JavaScript.

Nim's polymorphism is implemented by the compiler to determine the type, such as the previous oneaddThere can be manyadd,

proc add(x: Y, y: Y): Z =
  discard

proc add(x: P, y: R): Q =
  discard

Meet later(j, k)Polymorphism can be realized when compiled according to the type.

Of course, this can be achieved in JavaScript by class, but then you must tie the data operations together.

If you have long-term use of languages ​​affected by Scheme, it will be difficult to adapt to the bloated practice of class.

If there are types, it is natural to overload in this solution, such as Nim's typeADefine equality judgment writing method like this,

type A = object
  x: number

proc `==`(x, y: A): bool =
  discard

Not coupled together means I quoteATypes can also be expanded by themselves in another project, and this is based on type and will not be modified into the original module and will not affect other codes that reference A.

This is a headache for my code to translate from Nim to TypeScript, because I need to overload these array accessing and equality when defining the access and judgment of data structures. I can't think of how to do it in TypeScript for a while. I can only use mutable data to force simulation at runtime.

Nim is very simple, I'm right[]Reload it, and you canys[index]Used directly:

proc `[]`[T](xs: MyList[T], idx: number): T =
  discard

This is also similar to the iterator scenario. If you define iterator, you can write for..in directly.

Iterator is also OK in JavaScript, it just means that many operators in Nim can be reloaded by themselves.

Then the benefits are also quite obvious. For example, I refactored the internal implementation of the operation, but the use of the locations basically does not require adjustment.

And in JavaScript, I have been accustomed to facing Array and Object directly for a long time.

I have never touched Java and C#, and I have touched the language of this gameplay that is quite similar to Haskell. When Haskell generates instance from class, it is very flexible.

(Specific Haskell type class advanced gameplay is really not enough to play.)

However, compared to Nim, simplification is simplified, but this syntax sugar is very convenient in encoding.

Because of the lack of this function, I am a little uncomfortable with Clojure and TypeScript.

Types of dynamic data

The problem I found in the translation code is that JSON and EDN are extremely convenient, which caused me to directly use Array and Map to directly represent data in a large amount of code. This cannot be wrong, but the data in Nim is clearly represented by types, which also means that there is a clear structure in Nim for judgment, explicitly...

In contrast, my TypeScript code has a large number of, and then there is one I don’t know what to saytypeof x === 'object'The embarrassment, after using it in the type system, I turned around and felt very uneasy, and then I automatically ran to make trouble.instanceofThe gameplay is used to make corresponding functions.

Of course, JSON or EDN generally represents various data, which is indeed very good for general types. I call data across projects, and these dynamic types are directly general structures. In Nim, passing data generally involves some type conversion, and writing is a bit troublesome.

I'm not very good at measuring that solution is better, but for the underlying class library, I want to have clear types.

Memory-related issues

Because it needs to be compiled to C to run, the data structure in Nim still involves a little memory.

Fortunately, most of the pointers in Nim have been packaged into ref, and they rarely have to worry about them.

The main thing is that the performance differences between different data structures are easier to reflect.

In JavaScript, JIT always secretly helps with optimization, and it is not so easy to detect when writing problems yourself.

I feel that if I had used Nim earlier, the hazy feeling of algorithms and performance would have been much lighter.

Being able to touch memory means that memory management will encounter some problems. I encountered it before, and it seemed that when I was using macro, I encountered an error in the internal code of the language, and then illegal memory access, which became very helpless. The help given to me on the forum asked me to compile the Nim compiler itself and then log to get the details. This experience is quite novel. Anyway, I have not compiled V8 with parameters myself...

At least I don't need to have a clear understanding of the memory layout details as I have used so I'll see it later...

Some syntax details

There is still a lot of syntax sugar in Nim, and there is a lot of the light feeling when using CoffeeScript. For example, JavaScript is not easy to add language-level range now, so this is used directly in Nim...or..<You can generate range:

for i in 0...<n:
  echo i

Then if in Nim, although it is a bit unpleasant than CoffeeScript, it still has an expression:

let a = if b:
  c
elif d:
  e

Such code becomes very long immediately when you go to TypeScript, and I can't sacrifice readability with ternary expressions.

Of course, if you compare it with CoffeeScript, Nim still needs to consider the type, and it is not as flexible as it is.

For code formatting, Nim has a built-innimprettyOrder.

I didn't use it much, I just tried it, of course it's fast.

However, I have already managed spaces accurately by writing code with indentation. It seems unnecessary to make another one, and it is not flexible to write it.

other

I cannot admit that TypeScript is powerful. I am quite looking forward to AssemblyScript for this.

But with these feelings brought by Nim, I also had some doubts.

For example, based on WebAssembly, we will have a better browser language in the future. How can we do it better?

On the one hand, we must take into account the scenarios where a large number of interface processing of Web applications are used. On the other hand, high performance and flexibility, simple AssemblyScript is still not enough.

The above is the detailed analysis of the detailed use of TypeScript Nim. For more information about TypeScript Nim usage, please pay attention to my other related articles!