Re: A critique of Nim
I don't really understand why "a new codebase is easy to learn" has anything to do with where stuff "was actually defined". Either you can navigate easily through the codebase with your editor/tooling or you cannot. And if you cannot, putting the module name in front of everything doesn't help either, you still have to manually open the file and then search for the declaration within this file, so it's a search either way and you might as well start with the search operation. (grep on the directory instead of on the file, for example).
Re: A critique of Nim
I sympathize with @perfecto25 on global imports. They make a new codebase hard to learn because it's never clear where anything was actually defined. I usually start with `from foo import nil`. When needed, I add specific symbols, e.g. `from foo import []=, %, ...` And eventually, at least for standard modules, I might end up importing an entire module here and there. However, there is a very good reason for the Nim default, as @mratsim says: "unified call syntax". In C++, you often call `instance.method(x, y)`. With that syntax, `instance` is an implicit extra argument to `method(this, ...)`. I'm not sure that's good style, but everyone is used to it by now. Nim _allows_ that, but it also allows `method(instance, x, y)`, which is more explicit. And in Nim, they are synonymous. This "unified syntax" has subtle advantages (which I won't describe here). If you did not import "method", then you must specify the module, `mymodule.method(instance, x, y)`. In that case, the "instance.method()" syntax would not work at all. Also, Nim templates are powerful and convenient, but they often expect you to have imported the necessary symbols already. As a result, if you use a temple from some other module, you need to know the _implementation_ of the template so that you know what you need to import. You can usually learn these from compiler warnings, but it's often easier to import globally and be done with it. So this "problem" with Nim imports is actually a result of _features_ of Nim that are generally not available in other languages.
Re: A critique of Nim
Hello , I've been with NIM for 4 weeks (big full days;)) I come from IBM38 / AS400 43 years of practice and C / C ++ 30 years of practice, and Pascal I kept the structure and method. my reaction to hot foundry: Nim is much simpler than one imagines, very often I leave with a concept C ++, finally of account it is enough for me to remain open to understand what I can do with Nim and not to want to impose to him to do, I think like that, later I could think about imagining Nim thinking. I quickly got tired of the tutorial, I prefer to have a concrete project but that did not stop me from returning to the tutorial on the contrary, more by doing the introspection of imports, I understand better what we can in shoot . With practice I turn to the "template" but I'm not there yet it comes slowly as I advance. I have practiced a lot of POO or rather the ROO programming relation object object, I think that the language so ready finally I will see. On the other hand I bump into the real difference between func and proc, because I feel that proc is enough, and then the pointers history is the right solution and can we use it as in C / C ++, I still bump into simple things like data type conversion, the structure of the program is an excellent thing and allows to quickly have a style, the tutorial answers this question, I would have liked to write in English , so my translation Google! ( poo = OPP loll) I hope to be clear although these are concepts. ps: the doc should support with more concrete examples, i know easy to say and it takes a lot of time.
Re: A critique of Nim
I wouldn't be so harsh. Sometimes things seem so "obvious" that it doesn't occur to you that you may be wrong. I think this can happen to everyone. As the article I linked points out, the imports in Nim are often misunderstood. When I learned about Nim, I was also at least a bit suspicious.
Re: A critique of Nim
There's a pretty good article on this subject at [https://narimiran.github.io/2019/07/01/nim-import.html](https://narimiran.github.io/2019/07/01/nim-import.html) :-)
Re: A critique of Nim
thats a cool opinion, having 0 language experience and extensively using language that does something opposite. would be nice if people instead of imagining things and speculating how they could work actually tried to use them.
Re: A critique of Nim
I think the imports in Nim are great. Absolutely no complaints. And I do large projects.
Re: A critique of Nim
Nim is statically typed, unlike Python if you call a function from the wrong module you will not compile. Always prefixing with module name does not play well with the unified call syntax of Nim. Lastly, on big projects you can choose to use modulename.function(arg0, arg1, ...) in your codebase. But like code style, linting and code organization, this is a social contract between all contributors. Nim gives you the choice between using the Python syntax or a lightweight syntax, you're free to enforce the module.function(arg0, arg1, ...) in your code. Also, C has been doing it that way for 30+ years. Now that said, I agree that it's less easy when reading random code on Github, however just looking at arguments' types should help knowing which module the function came from. On your machine you have your editor that does that for you.
Re: A critique of Nim
great take on nim, totally agree on module import method being inadequate, esp coming from python in Nim, everything is this, import os which really means, from os import * this is fine for small projects, but if youre importing several modules in same file, you quickly lose track of what function is from what module, since module namespace is absent that seems like a crazy way to import stuff.
Re: A critique of Nim
I came to this by googling "NIM criticism", which I guess I did because my impressions of the language (only reading about it so far) were so positive that I thought I might be missing something. I wonder if @drslump ended up following @dom96's suggestion to "...please report these things". I think drslump's point about the visibility of the macros feature (which apparently is _not_ the fault of the core NIM developers, but that doesn't imply there is nothing to be done) over features that are more limited but arguably better for longevity, was somewhat misunderstood.
Re: A critique of Nim
I think an issue with letting the end users rate modules is that bad ratings will linger even after the module is improved. But it would be great to have some way to show that a module is not stable or reliable yet. Of course it's possible to just write it in the modules documentation, but that's to easy to miss. It should be visible from the [module list](https://nim-lang.org/docs/lib.html) whether a module is deprecated/stable/experimental.
Re: A critique of Nim
My learning experience with Nim, the language itself, is exceptionally pleasing and intuitive. I am able to program useful and fairly complex data analysis algorithms in short time. An area where Nim can be more helpful for me is communicating the various levels of maturity of the individual modules that I import. I want to way to understand their usability before I embark on programming at a deeper level and investing time. In many cases we do see the notice indicating Beta or Expreimental or that something might significantly change in the future. As a user, I would love to hear other hints on the use-ability of a module that is put out there (regardless of the phase in its development cycle) and let me explain this further below. As an example, the postgresql module is a work-horse for me. From my first exposure to it everything just worked and kept working. For mongodb driver I cannot say the same thing. The examples cited in its documentation are very pleasing but to get it work in reality takes longer time than what I am able to invest in. I wish I had known this before I embarked. I salute the work when a volunteer developer contributes to a module and we all know that it takes time to harden a product. I realize that in voluntary development work the implementer has limited time and money to put into their project. So on one hand we want to encourage all kinds of development work to happen without any hindrances or imposing our "expectations". Nevertheless a product is put out there for people to pickup and the programmer got to know something about the time and effort to deploy it as per the specification advertised. One suggestion is to have a end-user rating system (zero star to five starts) on usability in the module documentation perhaps. That is, whether (1) an end-user is actually using the module in something that is fairly interesting and (2) how pleasing the user interface (completeness/bugs/confusion with an api, etc). Just some thoughts, adding here another data point to this conversation.
Re: A critique of Nim
I use `nimgrep` for its convenient `--recursive --stdin --pegs --ext:nim` switches, not for its `-y` switch. As I said, the flexible casing is irrelevant in practice.
Re: A critique of Nim
> Not a huge issue but it breaks a common work flow that many developers bring > from other languages and I have no clue how to solve it. [Sounds like you need this](https://nim-lang.org/docs/nimgrep.html) But I understand where you come from. All I can say is that, as a guy who uses Linux + vim + sed/grep/awk religiously, I never ran into problems like those. I personally deviate from [the Style Guide](https://nim-lang.org/docs/nep1.html), in that I always use `snake_case` because I can't stand `CamelCase`, but as I said, it never created any problems for me in practice.
Re: A critique of Nim
> All are prefixed by a keyword, so you can grep for "proc myProcedure" and > find the definition of myProcedure. Sorry I didn't make it more clear. Sure there declarations are keyword prefixed in Nim but there is a bunch of them and I've had some issues with callables: I see `foo(v)` in the code, then search for foo which is not in the current file, so implicitly imported but from which module? then you look on all files for `foo` but it's a pretty common name, `proc foo` turns out nothing, maybe `template foo` ... and then if it had been `fooBar` you need to take into account that it might be defined as `proc foo_bar`, etc. Not a huge issue but it breaks a common work flow that many developers bring from other languages and I have no clue how to solve it.
Re: A critique of Nim
In general I agree with most things you've mentioned. Thank you for taking the time to write this :) I especially agree with the `system` module changes, @amalek implies that this is going to be done for 1.0. As it stands right now, the [v1.0 milestone](https://github.com/nim-lang/Nim/milestone/2) doesn't include this as an issue so this doesn't seem to be the case. It's possible that we will remember to perform these changes, but I think a better idea is to report them and ask us to add them to the 1.0 milestone. Otherwise there is a high chance we will release 1.0 and completely forget about such things (we are indeed really used to the status quo so it's becoming difficult to see the rough edges, since we just learned to avoid them). So yeah, please report these things.
Re: A critique of Nim
> > I think grep is always a last resort tool as it doesn't understand any > > programming language... > > [...] Many modern languages are easy to grep since they prefix declarations > with a keyword but in Nim this is slightly harder, I'm not advocating to > change the language for this, just that it might be worth to guide new users > with best practices to navigate a Nim code base. Perhaps I am misunderstanding you here, but AFAIK Nim does prefix declarations with keywords: proc myProcedure(): int = 42 var myVar = 42 let myLet = 42 const myConst = 42 Run All are prefixed by a keyword, so you can grep for `"proc myProcedure"` and find the definition of `myProcedure`.
Re: A critique of Nim
> I don't think it would be a good thing for Nim to change its syntax to > appease every single guy who comes along I think you're reading me all wrong, I'm not interested in changing the syntax, I don't care if `const` or `static` works better, not my intention to redefine the language at all! What I'm trying to express and provide feedback about is the on boarding experience when starting with Nim.
Re: A critique of Nim
> don't know what you're referring to with a "run-time" substitute for macros, > but it sounds like it would be very slow. Yeah, sorry, it's clear I didn't explain properly that. I think I've clarified it on the response to Araq. > This paragraph leads me to think that you're coming to Nim from Python. I'm indeed familiar with Python but I wasn't expecting Nim to be a typed version of it. Now that you mention it, the language marketing is working well in that regard, because it's true that due to the syntax similarity it's easy to make that association. > This is just not true. The manual itself states the following: ... Great! I think that should be much more exposed on the documentation. I think that it's almost part of the design philosophy of Nim to be honest, so it should be much clearer to any newcomer in my opinion. > Also, neither Nim's homepage nor its GitHub page have any reference to macros > whatsoever. I don't know what makes you thinks that Nim forces > metaprogramming down your throat. In fact, it would be very helpful if you > could point at which piece of information lead you to believe that so that we > could change it. That's a fair point, it might be a _confirmation bias_ since I do like metaprogramming and I might have been unconsciously looking for hints of it everywhere. The [features page](https://nim-lang.org/features.html) mentions _metaprogramming_ explicitely though, even with a `macro` example. The [wikipedia page](https://en.wikipedia.org/wiki/Nim_\(programming_language\)) screams metaprogramming too. It's a hard problem to solve though, on one hand the functionality is there, it's very useful and sets Nim apart from other languages which is great. But using metaprogramming is just **too ergonomic** in the language in my opinion, there should be some artificially placed resistance for it in a way that it's a tiny bit harder to implement one but remains frictionless when using them. > That said, I don't find Nim to be as big of a language as you make it out to > be. When I think of big languages, I think about things like C++, Rust, > Common Lisp, modern Java, modern C#, Scala, etc. It certainly doesn't try to > be minimalistic like Scheme or Go, but I don't find it excessively big. Let me put it another way, the problem I see is not that the language is big but that its size is _flattened_ and you have to confront it early on. I think C# for example does a great job here, so realize it's size when you deep into it, unlike Scala that is on the opposite extreme. Taking those examples, I don't think Nim should try to be Go but it should try to be perceived at the level of complexity of C#. Specially because its syntax is so approachable that I'm sure lots of users are tempted to try it, it's the on boarding experience what needs work in my opinion. > I disagree strongly about the GC stuff being useless though. Nim has by far > one of the best GC implementation when compared with other mainstream > languages. It's very useful to game programmers (and there are lots of us in > the Nim ecosystem). I didn't say that. Just argued that from a marketing point of view it doesn't make much sense to advertise the different implementations, instead it should focus on the different types of software that Nim helps you create. If that's mapped to different GC implementations or a single one that can be tuned belongs to a section in the manual not on the marketing site. The other point was that I'm not sure if supporting all this options in the main project might be too much work when the focus seems to be to reach a 1.0 stable release, but that's just me guessing, I don't know anything about the maturity of those implementations or the bandwidth of the development team. I shouldn't had included that highly subjective opinion sorry. > I also disagree about the community being unpleasant on GitHub. Technical > discussions should not take into account feelings. See Linus and its > methodology: it works. You should be able to separate between criticism aimed > at your work and personal offenses. Agree that _technical discussions_ should not take into account feelings, it should be based on the merits of the implementation and take into account lots of factors (mainteinability, complexity, documentation, etc.). The problem is that when interacting on GitHub I don't know you and you don't know me, so a bit of courtesy can go a long way. I'm sure even Linus will say "hi" and "thanks" when going to the grocery store, so I don't understand why the interaction on a pull request should be any different. The review process needs to be totally technical but there is also a tiny part of human interaction going on, thanking someone for his time when closing a PR or an issue is a little gesture that makes the project more approachable in my opinion.
Re: A critique of Nim
`static: const block` `proc ... {.compileTime.}: const proc` I strongly disagree about these two. What's wrong with the `static` keyword? It comes from C and that's what has always been used to signal things that should be either included into the binary itself or be executed at compile time. Also, you don't need to annotate a procedure with `{.compileTime.}` in order to use it statically. For example, you can write: import hashes const myhash = hash("foobar") static: echo "Compile time: ", myhash echo "Run time: ", myhash Run All you need to do is use the `const` keyword and Nim will try to run the proc at compile-time. On the other hand, I can understand you feeling weird about `when`, since it's a very rarely used keyword and it has completely different semantics in C#, but if you really want to propose a different syntax, wouldn't something like `static if` make more sense? The keyword `const` usually refer to a value, and `if` statements in Nim don't return values (there are `if` expressions, but those are a different thing). But let's be honest: is `when` really a problem? [The manual explains it very well and in a very synthetic manner](https://nim-lang.org/docs/manual.html#statements-and-expressions-when-statement) I don't think it would be a good thing for Nim to change its syntax to appease every single guy who comes along.
Re: A critique of Nim
> I'm not interested in arguing about the merits of each approach. My point is > that if you're writing a new OS then it would make sense to introduce a > better alternative to command line parsing, but Nim is a programming > language, it will be used in multiple operating systems and all of them seem > to be converging into Posix style CLIs. Yes, Nim works on many OSes and the colons mean tools like `nimble` can do perfect argument forwarding. No merits of the status quo are known. ("I cannot type colons" does not count.) Sorry, I don't have to invent a new OS in order to improve the status quo. Alternatively I could also argue that the Posix way of dealing with this is underspecified and Nim adheres to it already... ;-)
Re: A critique of Nim
> "Posix best practices" means ambiguous CLI switches that require a symbol > table to parse. Not much of a "best practice" here, it's just bad design that > you prefer because it's slightly easier to type. I'm not interested in arguing about the merits of each approach. My point is that if you're writing a new OS then it would make sense to introduce a better alternative to command line parsing, but Nim is a programming language, it will be used in multiple operating systems and all of them seem to be converging into Posix style CLIs. > I think grep is always a last resort tool as it doesn't understand any > programming language... Sorry, I think I didn't explain myself correctly. I'm not referring to the `grep` tool in particular. It's very common among users to navigate code by searching, specially if you're looking at the code of others, which can be with `grep`, any of its more modern alternatives, editor in-built search feature, etc. Many modern languages are easy to _grep_ since they prefix declarations with a keyword but in Nim this is slightly harder, I'm not advocating to change the language for this, just that it might be worth to guide new users with best practices to navigate a Nim code base. > You can productive in Nim without templates and macros, but we can't offer > "runtime alternatives" for these features. Totally agree, and I would say that the language already provides ways to implement most software without having to use templates or macros. But somehow my initial intuition was that it wasn't the case, I think that perhaps the issue is having several keywords with compile-time semantics, maybe if the language had a prefix keyword to introduce them the on boarding would be simpler: * `when`: `const if` * `static`: `const block` * `proc ... {.compileTime.}`: `const proc`
Re: A critique of Nim
Only via google search results. I don’t recall any variation inside the official docs themselves. My suggestion was more around a newbie thinking “ah OK, so I can express this a few different ways, but all things being equal I should use the ‘default’” is probably more helpful than thinking each variation is valid. If somebody explicitly wanted to use a different form then they can make that decision. For a newbie like me, I just want to be told what to do in the first instance, until I can make an informed decision (which would almost certainly be to stick the the ‘default’.). That way, the community gets more consistency and it opens the way for formatting tools around the ‘default’ style. ATM, I didn’t get a sense of a ‘default’ style other than the fact a consistent style is used in the docs. This is all about reducing the number of decisions a newbie clambering up the “on ramp” needs to make. Give me a style guide, a source code formatter and we are good to go :-).
Re: A critique of Nim
> I also found the fact you can specify the same thing a number of ways, made > learning it significantly harder, because different examples are in different > syntaxes. I don’t claim the existing docs use different syntax, but it would > help enormously if the documentation used the same syntax (without > necessarily proposing a blessed syntax), with a page up front warning against > macros AND describing the various syntaxes. Examples here would be most welcome. Where is that confusing syntactic diversity to be found?
Re: A critique of Nim
This is actually a very well written critique. Usually we get things like "MOMMY! T-THAT GUY'S LANGUAGE IS NOT CASE SENSITIVE! M-MAKE HIM STOP!!!" However, as Araq said, there are a few things which are incorrect. It's not actually your fault: in fact, it's actually a documentation problem. But let's go over them one by one. > That's why I think that any language that offers these [metaprogramming] > capabilities must make them gradual (i.e. generics vs templates vs macros) Well, that's exactly what Nim does. But more on this later. > have awesome reporting/debugging stories for it It does. Have a look at [treeRepr](https://nim-lang.org/docs/macros.html#treeRepr,NimNode), [lispRepr](https://nim-lang.org/docs/macros.html#lispRepr,NimNode), etc. and their relative `dumpTree`, `dumpAstGen`, etc. macros. These are totally equivalent to the same tools you get with other languages that support macros. Unless you're referring to some other very specific feature which I don't know of. > offer always runtime alternatives to the meta-programing so the language is > useable and productive without them What exactly do you have in mind here? I'll just note that [Nim's GitHub page](https://github.com/nim-lang/nim) states: > Nim is a compiled, garbage-collected systems programming language with a > design that focuses on **efficiency** , expressiveness, and elegance **(in > that order of priority)** Again, I don't know what you're referring to with a "run-time" substitute for macros, but it sounds like it would be very slow. Metaprogramming is necessarily a very resource-intensive task. That's why macros are usually a compile-time only construct, and the few languages which lets you modify the AST at runtime don't even try to be efficient (eg. the Lisp family). > Once you start with the language, the first 5 minutes feel great, if you're > familiar to the significant whitespace syntax it makes you feel at home and > with a promise of great performance! But then the illusion breaks, [... > cutting for saving space ...] you might not even know that you can override > operators in Nim at that point! This paragraph leads me to think that you're coming to Nim from Python. Now, while Nim's syntax certainly is very similar to Python ([so similar that something like this is very possible and it works wonderfully](https://github.com/yglukhov/nimpy)), trying to be a substitute for Python isn't Nim's main goal. Neither its second, third or fourth goal. **That is, you shouldn 't approach Nim as a "compiled, statically typed Python", but rather more as a "C/C++ replacement with modern syntax, package system, metaprogramming and much more"**. Essentially, **Nim is not to Python what Crystal is to Ruby**. > Unfortunately while some higher level constructs like generics are well > defined and understood at large by many users, full blown AST macros is a > different story. It's a very powerful tool with lots of sharp edges and > probably only seldom needed. In Nim however you're almost encouraged to use > them and I think that's a mistake, there is already a great higher level > general purpose meta-programming tool in the form of template (without term > rewriting), that should cover most use cases so any reference to real macros > in the docs should be prefaced with there will be dragons. **This is just not true.** [The manual itself states the following:](https://nim-lang.org/docs/manual.html#macros-statement-macros) Style note: For code readability, it is the best idea to use the least powerful programming construct that still suffices. So the "check list" is: 1Use an ordinary proc/iterator, if possible. 2Else: Use a generic proc/iterator, if possible. 3Else: Use a template, if possible. 4Else: Use a macro. Run Also, neither Nim's homepage nor its GitHub page have any reference to macros whatsoever. I don't know what makes you thinks that Nim forces metaprogramming down your throat. In fact, it would be very helpful if you could point at which piece of information lead you to believe that so that we could change it. But in any case, Nim is not Lisp. The vast majority of Nim's projects are written in a procedural style, with minimal OOP / metaprogramming added on top, and only when needed. Yes, there are things like [Jester](https://github.com/dom96/jester) which heavily use macros to build their own specialized DSL, but they are a minority. And in any case, I find Jester way more readable than its Ruby equivalent, Sinatra, if only because in Jester the DSL is "announced" with the `routes` keyword. > Anyhow, the main issue with the language is that from the very beginning > you're confronted with a huge cognitive load that is not easy to handle. Look > for example at the Official Tutorial, the surface of the language is too big > and while I'm not in a position to argue about the need or not of all
Re: A critique of Nim
That’s a great write up, and you’re English is infinitely better than my knowledge of your mother tongue :-). These are my thoughts as a very experienced dev (20+ years, primarily Java, Scala, Clojure erd) but a complete newbie with Nim. For me, it felt like there is a base set of knowledge that the existing documentation assumes. As it is a “systems” language (whatever that nebulous term means), maybe that is OK. For example, it compiles to C so it should be obvious how to cross compile, as that is done at the C level, not the Nim levelexcept I last did C 20 odd years ago. I also found the fact you can specify the same thing a number of ways, made learning it significantly harder, because different examples are in different syntaxes. I don’t claim the existing docs use different syntax, but it would help enormously if the documentation used the same syntax (without necessarily proposing a blessed syntax), with a page up front warning against macros AND describing the various syntaxes. For tooling, my main attraction to golang was the batteries included stdlib, and the ability to build a single static EXE for Linux and Windows was just great. It _[almost](https://forum.nim-lang.org/postActivity.xml#almost) made up for the compromises in the rest of the language! A “blessed” tool/process for cross compiling would be awesome. I put together an example docker for Linux and Windows ([https://github.com/yatesco/docker-nim-dev-example](https://github.com/yatesco/docker-nim-dev-example)) but it is nowhere near ready for production. It would also be worth writing a “LSP” adapter to the features in the nim conpiler. For maturity, the fact there are posts around from 2015 saying v1.0 was near, yet we still don’t see v1.0 made me very nervous. I think a highly visible roadmap to v1.0, even if the roadmap is for another 12 months! would give the sense of calm and confidence that the language is a maturing and ongoing concern. At the moment it feels like a kernel of gold surrounded by mostly platinum borders but some borders being cheap and frilly plastic :-). The community, in my experience is the main hook. It is an overwhelmingly welcoming and supportive place with people ready to step in and help (see the PRs to my docker project for example). Finally, @araq and team - you have built something _[really](https://forum.nim-lang.org/postActivity.xml#really) amazing here, and I take my hat off to you! I look forward to be part of the Nim community over the next 5 years as we slowly liberate programmers everywhere from the clutches of mediocrity and frustration from lesser languages :-). (Typed on an iPhone with chubby thumbs)
Re: A critique of Nim
Ok, I'll start with the minor note: > As a minor note, the CLI interface feels weird to me, I think I've used the > --opt:value syntax with Mono long ago. I think this just adds a bit to the > barrier of using the tool easily for no real gain. I would love a new nimc > binary that follows posix best practices for the CLI though. "Posix best practices" means ambiguous CLI switches that require a symbol table to parse. Not much of a "best practice" here, it's just bad design that you prefer because it's slightly easier to type.
Re: A critique of Nim
Thank you for this detailed essay. There are a couple of minor points I would disagree with, but I will keep quiet and see what others have to say. Btw import `lenientops` for mixing integral types like float and int.
A critique of Nim
# A critique of Nim ## Forewords This is an attempt to provide a constructive critique about the language from the experience of a new user. As such, Nim veterans should try to read it with some empathy and Nim novices should not take any statement as a source of truth. The core team should not think this is a personal critique to them, I have the utmost respect for the job you've done and I write this hoping that it can be of help. Moreover English is not my mother tongue, I've done my best to proof read it but I apologize in advance for any spelling or phrases that might be hard to understand. Please ask for clarifications if something is not clear before jumping to conclusions. ## Language ### First impression Nim has a distinct feeling to it from many other _upcoming languages_ , it promises efficiency via static typing while targeting the expressiveness of dynamically typed languages, all this without cornering the user into a safe subset that excels at a given domain but suffers for everything else. That's a great feature on itself, a language that's general enough that can serve you well for years to come no matter what the task at hand is. That generality however goes against the current trend of domain specialization in many languages, but to be honest, unless a language already has a killer app (i.e. Ruby on Rails) I think it's best to opt for that generality. I think this should be more emphasized on the website. As its distinctive traits there is of course the _significant whitespace syntax_ that will attract some people and disgust others, nothing can be done about it since it's a very subjective topic. Then there is the whole _meta-programming_ machinery, that while impressive at the technical level is a double edge sword for a language, some people will immediately discard it while others will love it and probably most of them simply won't know what is it good for. Unlike with the syntax however there are objective reasons to look with suspicion at a language with _meta-programming_ as a core feature, code is read much more than it's written and on many cases _meta-programming_ becomes an addictive joy when writing code, unfortunately others will have to read it later, maybe even yourself when the time passes. That's why I think that any language that offers these capabilities must make them gradual (i.e. generics vs templates vs macros), have awesome reporting/debugging stories for it and most importantly offer always runtime alternatives to the _meta-programing_ so the language is useable and productive without them. ### On boarding experience Once you start with the language, the first 5 minutes feel great, if you're familiar to the _significant whitespace syntax_ it makes you feel at home and with a promise of great performance! But then the illusion breaks, it's a typed language after all so the compiler starts behaving like your worst enemy. That's normal and expected, nothing wrong with the language, the on boarding experience though should be tuned for this crucial moment, preparing the user for that feeling. The compiler should help a bit, try to add an `int` and a `float`, suddenly you're exposed to a zillion overloads of the `+` operator all repeating the same message, you might not even know that you can override operators in Nim at that point! Then you learn a bit more, operator overloading seems so cool! You want to try by yourself and then you stumble on to something called template, which is a _meta-programing_ construct but it's a _simpler version_ of another thing that looks even cooler: `macro`. Suddenly you're exposed to a full new world that is very attractive and very _ergonomic_ to use, so your instinct is to go down that path. Unfortunately while some higher level constructs like generics are well defined and understood at large by many users, full blown AST macros is a different story. It's a very powerful tool with lots of sharp edges and probably only seldom needed. In Nim however you're almost encouraged to use them and I think that's a mistake, there is already a great higher level general purpose _meta-programming_ tool in the form of `template` (without _term rewriting_ ), that should cover most use cases so any reference to real macros in the docs should be prefaced with _there will be dragons_. It 's not Nim's fault that macros are hard, they are just a very blunt tool at a conceptual level and as such any implementation is going to flawed, that's why I think that Nim should place some resistance to its use, a pragma could probably be enough. ### A fews days in Anyhow, the main issue with the language is that from the very beginning you're confronted with a huge cognitive load that is not easy to handle. Look for example at the [Official Tutorial](https://nim-lang.org/docs/tut1.html), the surface of the language is too big and while I'm not in a position to argue about the need