- http://hookrace.net/blog/what-is-special-about-nim/
- http://hookrace.net/blog/what-makes-nim-practical/
Summary by benhoyt: https://news.ycombinator.com/item?id=8822918
* Run regular code at compile time
* Extend the language (AST templates and macros);
this can be used to add a form of list comprehensions to the language!
* Add your own optimizations to the compiler!
* Bind (easily) to your favorite C functions and libraries
* Control when and for how long the garbage collector runs
* Type safe sets and arrays of enums; this was cool:
"Internally the set works as an efficient bitvector."
* Unified Call Syntax, so mystr.len() is equivalent to len(mystr)
* Good performance -- not placing too much emphasis on this,
but it's faster than C++ in his benchmark
* Compile to JavaScript* Run regular code at run time - does this just error if you try to use const on something that depends on a runtime value?
* Add your own optimizations to the compiler - isn't this very dangerous, especially if optimizations from various sources of code get combined? Even if your optimizations are valid (which there seems to be no guarantee of), computer math is notorious for being different from real math. People unaware of the nuances of integers rolling over or floating point seem like they could easily shoot themselves in the foot here.
Yep. For example `const foo = stdin.readLine()` would result in "Error: cannot evaluate at compile time: stdin".
As for your second point. I haven't used this feature personally but I have heard that the compiler will tell you exactly where these optimisations are applied. You can also disable these optimisations very easily during compilation.
* Haskell can run regular code at compile-time (But it is slow, using ghci/TH)
* Haskell can add optimizations (rewrite rules and plugins). I think Haskell innovated rewrite rules and Nim probably was inspired by that?
* Binding to C easily is also a Haskell feature
* Type safe sets and arrays of enums: Is this not just a library? Haskell sets and arrays of enums are type-safe by default?
* Unified call syntax is true of Haskell too
* Compile to Javascript -- Haskell can do that too
- Predictable performance (lazy evaluation is problematic)
- Easy to achieve high performance
- Easier to read, even for non-specialists
- I'm much more productive in it
- Multi-paradigm: Nim is mostly imperative, but OO and functional can be mixed as well.
http://hookrace.net/blog/conclusion-on-nim/That's the point! I know many languages and Nim is by far the most productive one. It's like coding in Python with the assurance that the compiler will catch many errors that would cause runtime errors in Python. That assurance makes coding in Nim faster than in Python because I don't have to think so much about avoiding runtime errors.
Does Nim compile to C99 ?
If someone were to ask what's wrong with Nim, what would you say are the things that need to be fixed?
There are quite some compiler bugs remaining in Nim and the standard library could be improved.
* Yes, with compiler plugins
* Yes, with macros
* Maybe. I think that you could use a compiler plugin
to do arbitrary transformations on all the code in a
module, but I haven't seen an implementation.
* Yes
* What garbage collector?
* Yep
* Kind of. Any method can be invoked as a function with
the <type>::func(val, args...) syntax, but the
opposite's not true.
* Check
* Yep, via Emscriptenhttps://www.reddit.com/r/rust/comments/2yfsi9/rust_to_js_wit...
Transpiling to C gives you the opportunity to emit code that is straightforward clean and fast C for most operations, which avoid an abstraction overhead.
Before you reply to disagree, make sure to very, very carefully think through the implications of the last sentence there. It is not as if compiling to C is particularly hard; it is literally "homework assignment for a normal college senior in a compilers course"-difficult. Many languages have gone through a phase where they compile to C. Usually they deliberately leave C at some point, another thing to carefully ponder the implications of before replying in disagreement.
Yeah, and you could do this too at the start of your emitted code from the transpiler:
sleep(UINT_MAX)
which would also make it slower than an interpreted language. But I specified I wasn't talking about that, or about "just inlining the core interpreter loop", but about transpiling letting you also emit straightforward and clean code without extra abstractions for most operations.
A new language like Nim doesn't come with all the baggage of Python's runtime pre-existing, and doesn't need to recreate it.
That's reality from a company with a shitton of money and a vested interest in doing it successfully.
They can't do it in the general case because reality disagrees with you.
What I said: "unless done badly" (my words on the original comment), it's fast, as it gives you a chance to emit straightfoward C code for most operations. Now, regarding your example:
First, HipHop is not transpiled to C. It's a runtime with a JIT.
Second, what does "HipHop not supporting the entirety of the PHP runtime" has to do with anything?
I take it you mean that the fact they had to skip some parts of the runtime for increased speed, proves something related to what I wrote. But (besides the JIT thing) PHP is not greenfield like Nim. They have a runtime, and it has to work in a certain way. PHP wasn't designed with transpiling in mind, and HipHop had to follow it closely as a design goal. I never said runtime decisions you have to mimic to be 100% compatible can't slow you down.
> HipHop for PHP (HPHPc) is a PHP transpiler created by Facebook. By using HPHPc as a source-to-source compiler, PHP code is translated into C++, compiled into a binary and run as an executable, as opposed to the PHP's usual execution path of PHP code being transformed into opcodes and interpreted.
Still, how does the original version of HipHop as a transpiling compiler invalidate what I said?
I said (check my original comment): unless you do it badly, transpiling to C gets you to run faster, because it lets you translate most operations to straightforward and fast C code.
And that's exactly the logic they followed and what they achieved: they transpiled PHP to C, as opposed from running it with PHPs runtime interpreter, in order to make it faster, and it worked.
That they skipped some parts of PHP runtime behavior/semantics, which if they didn't it would slow things down, doesn't clash with what I said. In fact it's already covered in my comment: "it let's you translate MOST" (not all) operations to fast C code.
You're changing the context.
> while being fast since it's compiled to C. - them
> being compiled to C doesn't imply fast :) - me
> Unless done badly, it does. - you
You've switched to "faster" because it's a more defensible position, but that isn't the idea that was originally being responded to. That's why jerf said the following, emphasis mine:
> No, it doesn't. You could easily compile Python into C (basically, "just" inline the core interpreter loop), __but it will still be slow__
Which is fast compared to what? Being compiled to JS?
It's not like being compiled to a "fast language" automatically makes that compiled program fast. You also have to consider how complex the runtime is, and other variables which are probably a direct result of the semantics of the language.
foo = cast[ptr Foo](alloc(sizeof(Foo)))
# do stuff with foo
dealloc(foo)
EDIT: Here's the documentation on the site itself. Most things are 'traced' by the GC, but by using alloc and dealloc you can work with 'untraced' (i.e. manually allocated) memory: http://nim-lang.org/0.11.0/manual.html#types-reference-and-p...So it is Go++ if you wish.
But I am not sure about its concurrency. Go does have channels which are nice abstractions for doing concurrency right.