A Quick Comparison of Nim vs. Rust
arthurtw.github.io
arthurtw.github.io
Also:
> mapWidth, mapwidth and map_width all map to the same name
Why or why? Editors and IDEs now need Nim-aware search code!?
In Java and C# there are pretty widely adhered to coding standards. It's quite hard to find libraries that don't have consistent public APIs with these standards, and those that differ are usually subject to rumblings on their mailing lists and issue trackers.
In C++ there is no agreed upon standard. The standard library uses lower_train_case for all (public) types/members, and much 3rd party library code uses PascalCase and camelCase. The C++ standard library has fewer features than the Java/C#/Python standard libraries, and so you end up bringing more 3rd party code into non-trivial projects (in my experience).
If this feature existed in C++, a codebase could be much more internally consistent. However I'm still not sure I'd like this feature to be available. Certainly it's not possible to add it after-the-fact due to potential conflicts between members that differed by case.
Hopefully they'll add a Smalltalk/Objective C style format one day.
> Besides it would be trivial to write a refactoring tool that can autoreplace all instances with the preferred form.
This should be part of the language if it's being so lax with identifier uniqueness. And if it's so trivial, you should write it so people can't complain anymore.
Could you explain it, then? An identifier refers to a single thing. I don't see having multiple ways to refer to that identifier as a win AT ALL—it may be a win for people who are too lazy to learn their own code base, but it makes code hard to read, hard to maintain, and hard to refactor.
Meanwhile, having an identifier unique makes it easy to index, easy to manipulate.
You don't. It's a terrible idea to mix naming conventions.
> amyAtePizza has the same meaning as amy_ate_pizza.
WHY?! What possible benefit could it have? Why would you be mixing styles in the first case? Why can't you just remember which style hopefully your entire code base uses?
Wouldn't it be a lot simpler to have a single style?
Nobody is arguing that you should be able to use multiple forms for different variables. They're arguing that you shouldn't use multiple forms at all.
This happens with Nim code too. Each programmer will have their convention, and will use it consistently. If you have a team, you establish a convention for the project: you need that anyway because people creating new stuff need a consistent way of naming things and you don't want to later rename everything after a heated discussion. So if you can't keep people on your team from using a project convention, you have a bigger problem than slightly different identifiers in a programming language.
Also, once you start using the different free naming conventions in Nim you grow inmune to them looking ugly. Just like when you know only one programming language everything else looks alien, but when you learn something else you expand your horizon and it stops looking so alien, and it stops being "harder to read". I jump from one convention to another without problem for each project as needed, and doesn't even bother me at all.
tl;dr it's not a big deal, don't let that stop you from learning a very nice language, you could regret it later
It's definitely unusual, but I think it works quite well.
Having code which is formatted as uniformly as possible is a huge boon. Rules are better than norms, especially if there is zero cost of enforcing them.
In my very humble opinion this idiom is amazing at the start of a language and then it handcuffs it and that is why we have Python 2 or Python 3 issues.
I use to use Python for statistical work and about 2 years ago I switched to R. R is VERY flexible and seen a huge change over the last 5 or so years. It has changed for me especially in the last 6 months with changes in what libraries I use. Using dplyr and other libraries my code is night and day different. We now have piping with %>% that changes me code completely and makes it MUCH more readable and quick to write code. I don't see anything like this happening quickly in Python.
But when it comes to short-term, one-off, or unimportant tasks, I agree that an emphasis on flexibility is welcome. There's a reason that TIMTOWTDI works so well for Perl in its original role as a shell scripting language.
That's actually not surprising: a large fraction of time is spent in the map lookup, which in Rust is implemented as a B-tree, thus lookup time is (mildly) dependent on the map size. If keys are lowercased before inserting them, the map ends up having fewer elements.
The Nim version uses instead hash tables, whose lookup time is near-constant (that is, excluding memory hierarchy effects).
B-trees are especially bad for string keys, because comparisons are expensive.
EDIT: From Rust docs: "Currently, our implementation simply performs naive linear search. This provides excellent performance on small nodes of elements which are cheap to compare". (emphasis mine)
http://doc.rust-lang.org/std/collections/struct.BTreeMap.htm...
I think the example used in the docs is your exact use case.
This bit:
let found = match map.get_mut(..) {
..
}
if !found {
..
}
can be replaced with match map.entry(word) {
Occupied(mut view) => { *view.get_mut() += 1; }
Vacant(view) => { view.insert(1); }
}Not criticizing, just curious.
http://doc.rust-lang.org/std/collections/
Use a HashMap when:
- You want to associate arbitrary keys with an arbitrary value.
- You want a cache.
- You want a map, with no extra functionality.
Use a BTreeMap when:
- You're interested in what the smallest or largest key-value pair is.
- You want to find the largest or smallest key that is smaller or larger
than something
- You want to be able to get all of the entries in order on-demand.
- You want a sorted map.I’ve updated the code and article with HashMap. It runs about 6~7% faster than BTreeMap.
This was not the case in my benchmarks: the Rust spent 60% of its time doing regex matches, 25% allocating strings and less than 6% manipulating the map.
Using rust-pcre would probably mitigate this problem.
> and libregex is optimized to avoid exponential blowup on pathological regexes. It's missing a fallback to the backtracking algorithm at present.
Maybe. RE2/C++ doesn't do any backtracking AFAIK, but it appears near the top of any benchmark I think.
You should also use the re module, PEGs is not nearly as optimized as PCRE.
Rust, as I understand, requires the Rust compiler to be compiled for the cross-target; is this correct?
Of course, it is harder to obtain cross-compiled versions of the Rust standard library at the moment, so what you say is likely true.
As for speed, please file a performance bug! We love to know where we're missing out on optimizations.
As for optional GC, didn't D haven't something along those lines?
AFAIK, most libraries won't handle that situation gracefully as they don't expect it.
For example:
proc printf(formatstr: cstring) {.header: "<stdio.h>", importc: "printf", varargs.}
I'd be interested in seeing a comparison of higher level language features rather than performance (which is generally a result of data structure choices, etc). Stuff like package managers, concurrency primitives, cross compiler support, memory management, and general syntax.It just didn't work out mixing Frameworks compiled in different modes, many times leading to crashes.
Polling a poorly implemented web forum speaks leaps and bounds about the kind of attitude you need to have to discuss, develop or debug issues around the Nim toolchain.
This is something that Nim developers can instantly do to boost the attractiveness of the language.
Please, do this.
Well, it's the kind of attitude that let me contribute to the language, and fix bugs despite being rather new to it all, so I'll be honest and say that I think it's quite good. Aside from that, the IRC channel is always super busy and amazingly helpful. I think a mailing-list is a good thing, sure, but it's not the be-all-end-all, in my humble opinion.
For example `from_str::<int>` should be `.parse()` today.
I did not add the case sensitiveness option to it.
Also, I find one of your statements quite contradictory: by saying that Rust's compiler "is written in itself", you seem to imply that Nim is not. But this is not true: Nim's compiler is almost 100% pure Nim.
(Last but not least: to me it seems not true that Nim "only compiles to C", as it provides multiple backends. See here: http://nim-lang.org/backends.html .)
Generally, the LLVM route will be faster/more compact when compared to Clang. However, nim can just as easily use gcc, or MSVC, or tcc, which rust cannot. Especially with respect to tcc, this means a stand-alone all-inclusive nim compiler executable can quite easily be constructed and will probably be ~1MB, whereas the comparable standalone rust compiler rustc executable is likely to clock in at 20MB. And you know what? That makes no difference in today's world.
Edit: made it explicit that I am talking about the compiler itself (which was the subject of the parent post I was replying to).
I estimated that the rustc will be 20MB based on my experience with linking LLVM statically in the past - I have not tried it recently, nor have I built rustc. I might be way off. Kibwen says his rust compiler clocks at 8MB - so it appears I am way off (or maybe comparing an unstripped executable to a stripped one)
To be clear to child comment: I did NOT intend to claim that writing something in C will provide a 95% reduction of code size.
EDIT: Servo, which is the largest Rust program in existence at the moment, is 21MB. Personally I doubt the above claim that writing this in C would reduce the binary size by 95%. I obviously don't have any statically-linked written-in-C web browsers on hand, but if I poke around in Chrome's install directory I see 85MB of DLLs (the entire directory is about 475MB, though surely not all of that is due to binaries).
Is the 8MB rust compiler statically or dynamically linked to LLVM? It's been a few years, but I never got a statically linked LLVM-using program below 30MB (unstripped, I think stripped was 16MB but I don't remember)