4 ms·
Nim isn't compiled to C in the same way that, say, Coffeescript is compiled to Javascript. Nim's compiler converts the AST into an intermediate representation
by adrusi 12y ago
Nim isn't compiled to C in the same way that, say, Coffeescript is compiled to Javascript.
Nim's compiler converts the AST into an intermediate representation that can be compiled to several backend. The primary backend is C source code, but it also supports outputting Javascript (experimentally) or interpreting the intermediate representation ala Python.
The difficulty of developing the IR -> C transformation certainly influences the features of the language, and certain features, like tail calls, can't be implemented because Nim expresses functions as C functions for the benefit of foreign code. I wouldn't say it's a leaky abstraction though, not any more than C is a leaky abstraction over machine code.
- dogprez 12y agoYour example isn't exactly true. Clang and GCC both do tail call optimizations. Compiling language functions to C functions doesn't 100% preclude you from TCO. http://david.wragg.org/blog/2014/02/c-tail-calls-1.html http://david.wragg.org/blog/2014/02/c-tail-calls-1.html
- bch 12y agoSee also: http://www.pipeline.com/~hbaker1/CheneyMTA.html http://www.pipeline.com/~hbaker1/CheneyMTA.html It looks like work/research in this area has been going on for at least ~20 years.
- jpolitz 12y agoIndeed it has. For a few more examples, see also http://www.ustream.tv/recorded/43777177 http://www.ustream.tv/recorded/43777177, and http://www.ccs.neu.edu/racket/pubs/stackhack4.html http://www.ccs.neu.edu/racket/pubs/stackhack4.html. Pyret (http://pyret.org http://pyret.org) uses similar stack techniques to these to simulate an arbitrarily deep stack while compiling to JS.
- pjmlp 12y agoIt will, otherwise semantics will depend on which C compiler is available and ANSI C doesn't require TCO.
- marvy 12y agoTail calls are pretty easy to implement in a language that compiles to C, even if the C compiler doesn't cooperate. This can be done without bothering the foreign code. For instance: int f(int a, int b){return f(b,a);} compiles into int f(int a, int b){start: int t=a; a=b; b=tmp; goto start;}