Yes indeed. I for instance can not wait Kotlin-native to materialize because... Because Kotlin has a usable IDE already. Nim is a great language, although rough on the edges. Add lack of libraries or need of wrapper generation to the equation, also add lack of a decent IDE.. I am privileged enough to have liberty of picking my battles so one of my requirements for getting work done is to also feel a pleasure doing it. Writing nim code in a notepad which has some IDE features that may or may not work (auto-complete from nimsuggest is really iffy, in source code of compiler especially) is suboptimal. Add debugging experience which due to various reasons is not greatest.. It is hard to justify using Nim over c++ or python. It is a shame though because language is really nice and with some polish it could be a great alternative to already established languages. Keeping fingers crossed for some brave soul coming forward and making IntelliJ plugin for nim.
The one thing that concerns me a bit is that identifiers are partial case-insensitive right?
(That means only the first letters are compared in a case sensitive manner. Other letters are compared case insensitively and underscores are ignored.)
Does it hinder when you need to do refactoring?
Also, I work in vim, and grep for stuff when I need. I am not sure if autosuggests and locating definitions/usage for variables would work. I am sure I must be wrong as I believe the core developers would have thought about it :) I just would like to know how
Every language seems to have a bizarro decision that kind of breaks it for many people. This is Nim's. It could be worse, it could be "Who need's Generics? They're costly anyway", like Go's...
It's definitely weird and I personally could take it or leave it. But don't let it dissuade you from trying the language.
The idea behind this feature is to let you choose which style you want to write code in.
Code I write for work these days (not including Puppet config, which is Ruby, or shell scripts) is all Python, and I still dislike the significant indentation. I do not dislike significant indentation per se, but I do dislike some of its effects in concert with other language design decisions. I did have a knee-jerk negative reaction to Python's significant indentation by itself when I first encountered the language a long time ago, but I got over it when exposed more to a couple other languages with significant indentation where it felt less off-putting. For instance, I never had a problem with Haskell's use of the off-side rule for specific block types (though I'm far less familiar with Haskell in general than Python), and did not even realize the language used the off-side rule for a while because it blended so seamlessly and naturally with the "obvious" way to organize code in every case where the rule applies. To repeat and clarify my feeling on the matter, though, I still dislike the off-side rule in Python, because of its interactions with other language features.
I don't want to distract from Nim discussion to create a whole separate debate, so I may not respond to further questions on the subject here -- I just wanted to point out that significant indentation is not devoid of its trade-offs for the benefits some people enjoy. I understand that some people like significant indentation so much that the other concerns that arise might end up beneath their notice, and others may hate it just out of some stubborn attachment to the conventions of other languages, but it is worth noting that it really does come with trade-offs, and there are also many people who dislike it specifically for the effects those trade-offs have on their code, and that this is a perfectly valid and reasonable position to take (even for those who find it difficult to identify or articulate the specific, undesirable causes of those effects they dislike). There are problems in practice, but not problems so big that one cannot reasonably ignore them if one likes the positive effects of significant indentation.
My usual solution to the problems Python's significant indentation solves would just be to fire people who lack such attention to detail that they cannot learn to format code nicely, though. As such, the language enforcing it offers less benefit for me than it might for others.
While I might not go as far as you here (firing), I think your underlying point about attention to detail is entirely correct and generally doesn't get the attention it deserves.
Lack of attention to detail re code style issues is probably an early (i.e. obvious) indicator for lack of attention to detail in other more important areas.
(Note: I say indicator, because it's entirely possible the developer just doesn't care about code style, or has a different preference, yet still has attention to detail for other more important areas)
Case insensitive and _ ignoring identifiers not so much -- they just add mental burden, encourage different styles in the same codebase, make things ungreppable without special tools, etc. And for what?
If the best one can say about a feature is "people still like the language despite it", it might be better to axe it.
Actually, case sensitive identifiers encourage this. If a library uses camelCase but your code base uses snake_case then you will be using a mix of camelCase and snake_case in order to use that library.
That is a real benefit and is entirely the point of this feature.
Which will be totally fine, as it involves different variables / things pointed at.
Whereas the "case/underscore insensitive" qualifiers lets you have 10 different versions of the same variable name, in the same codebase -- even without using any third party "library".
Besides, the problem of "third party library uses a different style" is easily solved by having a tool like go fmt that enforces a unique single style. End of story.
I can see the point though that grepping, and things like editors which highlight the selected variable would have to take these rules into consideration. It's a valid concern but I feel the benefit of clean unified code is more important.
Whereas referencing the exported identifiers from the library with a different style than they are written with in the library's code sounds more satisfactory to you?
I can see why you are skeptical of it but once you've used it for a while it becomes second nature. And you can always mix if you want to. The thing is that you can choose how you want to do it. And there are extremely few cases where the casing actually makes the identifiers different (keeping it mind that the first character is type sensitive).
Labels (e.g. variable names) coming with style insensitivity is indeed weird, and likely to be far more off-putting for many than significant indentation, though both put together will likely have even more of a negative effect on adoption, in my estimation.
I can imagine benefits to the style insensitivity, but I think those benefits could be had without a style insensitivity, and they come with trade-offs as well when you use style insensitivity to get those benefits (for instance, some typos could be ignored altogether by the parser, but cause the human eye to miss them or cause codebase searches to fail to find all instances of a label when using tools external to the language's implementation itself).
I think some of the benefits of style insensitivity are worthwhile, though, and should be pursued (by other means, preferably). For example, a language feature that allows one to define (with a single line of code, perhaps a pragma declaration) a standard for label formatting could be used to make library functions conform to your project's code style standards would be a much more palatable solution to the problem of alien code looking alien than style insensitivity, in my opinion. I think a (Proposed? In development?) feature of Nim -- syntax "skins" -- might offer exactly that, and it could result in effectively being able to turn off style insensitivity in your projects. If so, I would expect that to become the standard way to handle code style in Nim projects.
Unfortunately, it's unlikely that you can collect any meaningful data on how many people refuse to try it altogether (or put enough time into it for anyone in the Nim community to hear about it) because of style insensitivity.
It seems odd to me that Nim developers chose to go with that "style insensitivity" (which I would have predicted would be highly controversial and very discouraging for many, many developers) but indentation sensitivity (which is less controversial, but still more controversial than indentation insensitivity; shockingly large numbers of people dislike it, including me at least when combined with some other language features).
If the goal was widest possible appeal and adoption, those two decisions should have been swapped, I think. If the goal is related to some specific philosophical stance, however, I suppose every language developer who doesn't just want to recreate PHP or VisualBasic needs to pick the hill on which he or she is willing to die, and only time will tell whether it will be worth it.
Are you really only using case to distinguish different variables? That seems more error prone.
My Vim config for Nim can be found here: https://github.com/jboy/dotfiles/tree/master/vim (based upon https://github.com/zah/nim.vim , with a few improvements to my taste).
In particular, Vim syntax highlighting for Nim: https://github.com/jboy/dotfiles/blob/master/vim/syntax/nim.... and some convenient Vim mappings to jump around in Nim: https://github.com/jboy/dotfiles/tree/master/vim/ftplugin/ni...
I also use (and recommend) the CamelCaseMode Vim plugin with Python & Nim.
It has almost never been an issue for me and I don't use any case-insensitive refactoring tool. Just write variables in a consistent style and let completion help you stay consistent.
What would you say are the advantages of Nim over a language like Go? I see a lot of similar "value add" statements.
> What would you say are the advantages of Nim over a language like Go? I see a lot of similar "value add" statements.
In all fairness I haven't given Go a proper try. But my main problems with it, based on what I've seen of it, are the following:
* Lack of generics
* Lack of exceptions
* I prefer the Python-like syntax of Nim
* Metaprogramming in Nim is fun and powerful
* Lack of (official) package manager
Go does support multiple return values, commonly (T, error). If you think about it for a while, you will realize a exception is just a type of return value.
Regarding generics, the more I used golang, the less I had a need for generics. Also, there is solutions if you insist, such as https://github.com/cheekybits/genny
Sure, and Nim supports multiple return values too. But having to handle this extra value at every function call seems like it would get old really fast. I don't want to worry about every single exception when I am prototyping for example. Also, without stack traces, how do I know where an error comes from?
> Regarding generics, the more I used golang, the less I had a need for generics. Also, there is solutions if you insist, such as https://github.com/cheekybits/genny
Indeed, like I said, I haven't used it much so perhaps I would be able to live without generics. It is still very nice that Nim offers them though.
You are free to ignore the returned error, so for example to compare with a situation where you would raise an exception in another language inside a function, but not wrap the call in a try-catch:
val, _ := funcThatCanFail()
> Also, without stack traces, how do I know where an error comes from?
Go does have stack traces
No, they are part of the syntax. The compiler (in Nim and other languages) can track which exceptions are allowed to be raised in a procedure and which aren't at compile time:
https://nim-lang.org/docs/tut2.html#exceptions-annotating-pr...
type FatalError error
func foo() FatalError {} * Lack of generics
* Lack of exceptions
I don't see these items as being shortcomings. Go is simple and simplicity is elegance, and simplicity is something that cannot be found in most modern languages. Just look what happened to C++, It has become more like C# and Java.
Regarding Nim, I believe it's a nice language and I have done a few small projects using it but just like what I mentioned there are 10000 ways to do a single task and that sometimes is confusing.BTW C/Go/lua are my languages of choice
I don't like Go's explicit error handling because (1) I think it clutters up your main code path with error-handling logic, and (2) it forces you to always handle errors locally (even if that local code does not have the context to know how to handle the error) or return the error code through multiple layers of functions (back to where it can be handled).
That said, I completely agree that exceptions are also problematic. As you say, you can never really be sure of what exceptions can be thrown. Some languages have a "throw" keyword, in which you're meant to enumerate the list of possible exceptions; but of course, that's a headache to maintain, and is affected by inner code (such as library code) that might be completely out of your control or review. And when should the "throw" keyword be enforced, at compile time or runtime? And what should happen if the "throw" keyword's list of possible exceptions is violated?
Then of course there is the other problem with exceptions, the flip-side to being forced to handle an error locally: As your exception unwinds the stack, it might obliterate some local context that is needed to decide how to handle the error; or it might obliterate some local context that is needed to continue with your original task after the error has been handled!
The most interesting (and least broken) error-handling mechanism I've encountered is Common Lisp's "condition" system: http://www.gigamonkeys.com/book/beyond-exception-handling-co...
I see C++'s `std::set_new_handler` function [0] as C++'s less-capable equivalent to Lisp condition handlers. But the function invoked by `std::set_new_handler` lacks the ability to assess local context to decide how to handle the problem.
[0] http://www.cplusplus.com/reference/new/set_new_handler/
EDIT: I would love to see a language like Nim incorporate something like Lisp's condition system. Nim already offers "procedural types" (function pointers) [1] and closures [2] to capture variables from the enclosing scope. Nim even offers "anonymous procs" [3], to avoid the need to define new error-handling functions everywhere.
[1] https://nim-lang.org/docs/manual.html#types-procedural-type
[2] https://nim-lang.org/docs/manual.html#procedures-closures
[3] https://nim-lang.org/docs/manual.html#procedures-anonymous-p...
This is something that Nim offers via the `raises` pragma[1]. It is enforced at compile-time and in my experience works rather well.
1 - https://nim-lang.org/docs/manual.html#effect-system-exceptio...
[0] http://www.gigamonkeys.com/book/beyond-exception-handling-co...
Can we please let go of this meme? Many polyglot developers complain about the lack of generics, and how Go code ends up being more verbose and less expressive than languages like Python.
Things like interfaces and pointers to interfaces, structs vs slies and maps are not consistent.
Yeah, and inconsistencies are one of the things that make for a more complex language, not a simpler one. In fact, Go has generics, but they only work for magic, built-in types. I would argue that's less simple than just supporting generics, and building your standard library out of language features.
Edit: I just found from your profile, you are tha author of vim in action! I suppose that is where I start!
Be sure to join us on IRC/Gitter as well if you have questions: https://nim-lang.org/community.html#chat-rooms
It does use glibc, right?
I think it's moderately flexible to what is used because it transpiles to c first (afaik?)
> How has your experience been compared to your previous tech?
Previous to using Nim I was primarily using Python. This was a few years ago now, but recently I was working on a project in Python and found myself yearning for Nim. There were multiple reasons for this, but what stuck with me was how much I missed static typing. The Python project used type hints which I found rather awkward to use (of course the fact that we didn't enforce their use didn't help, but it felt like such a half-baked solution). Dependencies very often required multiple guesses and searches through stack overflow to get working. And the resulting program was slow.
As far as I'm concerned, Nim is Python done right. It produces fast dependency-free binaries and has a strong type system with support for generics.
Of course, that isn't to say that Nim is a perfect language (but then what is). For example, JetBrains has done a brilliant job with PyCharm. Nim could use a good IDE like PyCharm and with its strong typing it has the potential to work even better.
> How mature is the standard library?
To be honest the standard library does need some work. In the next release we do plan on making some breaking changes, but we always lean on the side of keeping compatibility even though Nim is still pre-1.0. Of course, sometimes this is not possible.
> How abundant are third party libraries?
Not as abundant as I would like. Great news is that you can help change that :)
The Nimble package manager is still relatively new, but you can get a pretty good idea of the third party libraries available by looking at the package list repo[1].
Hope that helps. Please feel free to AMA, I'd love to introduce you to our community.
1 - https://github.com/nim-lang/packages/blob/master/packages.js...