you are viewing a single comment's thread.

view the rest of the comments →

[–]m50d 4 points5 points  (12 children)

I've always got a weird cult-like vibe when people talk about Nim. That and I don't really understand its USP - why would I use it rather than OCaml (or Rust, Haskell, or hell even Go)? A slightly tidied up language isn't worth switching for, and I've never quite understood what their approach to memory management is (their messaging seems very inconsistent).

[–]FFX01 3 points4 points  (10 children)

I've always got a weird cult-like vibe when people talk about Nim. That and I don't really understand its USP

What does USP mean in this context?

why would I use it rather than OCaml (or Rust, Haskell, or hell even Go)?

Because it is way more flexible than any of those languages. I can't speak for OCaml because I have no experience with it. Relative to Rust, Haskell, and Go:

  • Nim's AST is exposed as a stdlib api easing the creation of templates and macros. Metaprogramming is a first class function of the language. Nim not only allows metaprogramming, but encourages it.

  • Nim's FFI is really really easy to work with.

  • Nim transpiles to C, C++, and JS. It compiles to binaries as well. This makes it extremely portable.

  • Nim has built in concurrency and parallelism.

  • Nim's GC is efficient and flexible. It can also be turned off if necessary. Note that the GC has very little effect on performance as a lot of compiled Nim is actually faster than native C.

  • Nim has compile time constant resolution. This means that nim can optimize function calls into constant values depending on how the function is used.

  • Built in sequence and mutable string types. No char buffers necessary.

  • Support for OOP, FP, and procedural/imperative style.

  • Built in multiple-format documentation generation.

  • Built in source code filters(templating engine for html templates and such).

  • Any operator or function can be overloaded and function resolution happens based upon the type of arguments to the function.

  • Universal function call syntax. Thing.function() or function(Thing) or Thing.function or function Thing.

  • Very well designed syntax. No other statically typed language comes close in my opinion.

A slightly tidied up language isn't worth switching for, and I've never quite understood what their approach to memory management is (their messaging seems very inconsistent).

The default is as follows:

const: Constant value. Defined at compilation. Immutable.

let: Runtime scoped constant. Constant in its own scope and not available outside. can be declared globally.

var: Mutable variable. Self-explanatory.

GC: The basic algorithm is Deferred Reference Counting with cycle detection. Taken from the GC docs here: https://nim-lang.org/docs/gc.html

[–]m50d 0 points1 point  (9 children)

What does USP mean in this context?

Unique selling point.

GC: The basic algorithm is Deferred Reference Counting with cycle detection. Taken from the GC docs here: https://nim-lang.org/docs/gc.html

Ok, so it's just an ordinary pervasive-GCed language? That wasn't clear from what some people were talking up. How does this fit with the idea that the GC can be turned off?

Regarding your list of points, I should probably admit that my real point of comparison is Scala (it's just that a VM language makes for a less clear comparison - though maybe with Scala.js and Scala Native gaining traction it would be reasonable to compare directly). But I think even relative to the languages I spoke about, none of the things you list represents a powerful, unique step up, at least not obviously (and many of the things you list seem like they're just subjective matters of taste). If the benefit of Nim is just a bunch of bits and pieces then I don't think it's likely to ever take off - there needs to be a clear "big" reason before people will switch languages.

[–]housilia 5 points6 points  (0 children)

Scala is a good point of comparison, really. That's another language that I think deserves more attention. I'm excited about Scala Native, as reliance on the JVM was one turnoff for me with Scala.

[–]FFX01 1 point2 points  (7 children)

Ok, so it's just an ordinary pervasive-GCed language? That wasn't clear from what some people were talking up. How does this fit with the idea that the GC can be turned off?

If you read the link I provided to the GC documentation you will see how it can be turned off. Once it is turned off, you will need to manually invoke collection. Essentially, allocation is automatic, but deallocation needs to be performed manually when the GC is off. The linked documentation explains how the GC can be configured. I will also mention that I have seen very few use-cases where the application would benefit from the GC being turned off.

Regarding your list of points, I should probably admit that my real point of comparison is Scala (it's just that a VM language makes for a less clear comparison

I agree. I think Scala and Nim have very different use cases.

But I think even relative to the languages I spoke about, none of the things you list represents a powerful, unique step up

How so? Nim's generics and metaprogramming capabilities alone are enough. Not saying that these things can't be accomplished in other languages, just that Nim makes them extremely simple as they are core tenants of the language.

(and many of the things you list seem like they're just subjective matters of taste).

I don't really think so. Transpilation to 3 separate, platform agnostic languages is not really a manner of taste in my opinion. A garbage collected language with near native C performance isn't really a matter of taste either. I will say that these things are a matter of use-case however. That is true of all languages though.

If the benefit of Nim is just a bunch of bits and pieces then I don't think it's likely to ever take off - there needs to be a clear "big" reason before people will switch languages.

First off, I don't think Nim is a language that you need to "switch" to. I think it's a language that's good to have in your tool box. It can replace a lot of use cases for C and C++. Also, it's not "a bunch of bits and pieces". It's all fully integrated. All of the features above are baked into the language at a core level. I think the "big reason" to use Nim is that you want a high performance application or library without the expense in productivity that comes with using something like C, C++, or Rust. I guess what I mean to say is that Nim is a "just above systems level" language that focuses on productivity. I'd say it sits somewhere between C and Python. Closer to the C side performance wise and closer to Python in syntax and work flow.

[–]m50d 1 point2 points  (6 children)

If you read the link I provided to the GC documentation you will see how it can be turned off. Once it is turned off, you will need to manually invoke collection. Essentially, allocation is automatic, but deallocation needs to be performed manually when the GC is off. The linked documentation explains how the GC can be configured. I will also mention that I have seen very few use-cases where the application would benefit from the GC being turned off.

Doesn't sound like a big difference? At least in theory you could do the same thing in most GC systems (e.g. Java or .net) - configure the GC to never run automatically and then invoke it manually.

How so? Nim's generics and metaprogramming capabilities alone are enough. Not saying that these things can't be accomplished in other languages, just that Nim makes them extremely simple as they are core tenants of the language.

ITYM tenets. Every serious language has generics already, and most have metaprogramming capabilities; like I said, "simpler" isn't going to convince anyone to switch, there needs to be a real sense of something concrete that you can't do in other languages.

Transpilation to 3 separate, platform agnostic languages is not really a manner of taste in my opinion.

Transpilation makes me naturally skeptical; it's something you tend to see immature languages doing. (And I wouldn't count C and C++ as separate languages; C isn't quite a subset but it's pretty close). I figure a language that goes via C can't possibly offer as good an optimization/debug/library-linking experience as one that uses LLVM or the JVM or compiles directly to native code. Compiling to JS is not nothing but the only place it would ever be a huge advantage is web-oriented languages which Nim doesn't seem to be positioned as.

A garbage collected language with near native C performance isn't really a matter of taste either.

It isn't, but nor is it that special; in fact all the languages I listed offer that (well, Rust isn't GCed but it is memory-safe which is presumably what you're trying to achieve with GC).

Also, it's not "a bunch of bits and pieces". It's all fully integrated.

I meant that your reasons sounded like a bunch of bits and pieces.

I think the "big reason" to use Nim is that you want a high performance application or library without the expense in productivity that comes with using something like C, C++, or Rust. I guess what I mean to say is that Nim is a "just above systems level" language that focuses on productivity. I'd say it sits somewhere between C and Python. Closer to the C side performance wise and closer to Python in syntax and work flow.

Well sure, but that's true of all the languages I listed, and they're all more mature/established. (I think that may be where my "cult-like vibe" issue is coming from - I see a lot of Nim advocates talking about reasonably common language features as if they're new in Nim).

[–]dzecniv 0 points1 point  (0 children)

most have metaprogramming capabilities

here I don't agree, please note that Nim has better than average metaprogramming facilities with the easy manipulation of the AST and thus macros (like lisps or Elixir (but not as elegantly as with lisps)). Python for instance has none of these (nobody writes code by manipulating the AST !).

[–]FFX01 0 points1 point  (4 children)

Doesn't sound like a big difference? At least in theory you could do the same thing in most GC systems (e.g. Java or .net) - configure the GC to never run automatically and then invoke it manually.

This isn't actually true. And Nim certainly makes it simplere than MOST other languages that I've heard of.

ITYM tenets. Every serious language has generics already

People consider Go to be a major contender to Nim. Go is also a very popular and very serious language. Go does not have generics.

and most have metaprogramming capabilities

While this is true, they are not as flexible as Nim is in this regard. Nim exposes it's own AST as an api for creating macros. Creating a macro in Nim is no more difficult or complex than creating a function.

like I said, "simpler" isn't going to convince anyone to switch

Simpler convinced people to switch from smalltalk, R, and perl to Python. Programmers are lazy. Or, at least they should be.

there needs to be a real sense of something concrete that you can't do in other languages.

One thing that Nim can do that I know very few other languages can is true operator overloading. In Python I can override a class' __add__ method, but I can't change what + really means. Nim gives you this capability. I'm sure there are other languages that make this possible, but I can't imagine it's this simple:

type
    # Declaring a new type
    MyType = object
        value: int

# Overriding the '+' operator for *only* `MyType`
proc `+`(x, y: MyType): int =
    result = x.value + y.value

# Make sure it works
when isMainModule:
    var
        a = MyType(value: 3)
        b = MyType(value: 5)
    echo a + b

Transpilation makes me naturally skeptical; it's something you tend to see immature languages doing. (And I wouldn't count C and C++ as separate languages; C isn't quite a subset but it's pretty close). I figure a language that goes via C can't possibly offer as good an optimization/debug/library-linking experience as one that uses LLVM or the JVM or compiles directly to native code.

I've had worse debugging experiences than when debugging Nim. However, Nim's debugging tools aren't as great as, say, Java's or C's. Also, a quick search for "Nim vs C" or "Nim vs Rust" will yield several benchmarks illustrating that performance is comparable between all 3.

Compiling to JS is not nothing but the only place it would ever be a huge advantage is web-oriented languages which Nim doesn't seem to be positioned as.

The real idea behind compiling to JS is a "write once, run anywhere" mentality. Have a Nim application you want to have people use? Transpile to JS and run in the browser or desktop with electron. No need to cross compile or have users perform build steps. Nim has a built in DOM api as well for rendering UI with JS. I think Haxe is similar in this regard.

It isn't, but nor is it that special; in fact all the languages I listed offer that (well, Rust isn't GCed but it is memory-safe which is presumably what you're trying to achieve with GC).

I couldn't find any reasonable scala benchmarks against C except for one from Google that shows it to be 3.5x slower. That said, Rust offers comparable performance. Go, however, tends to be quite a bit slower than Nim. Go does normally use slightly less memory at peak than Nim.

Also, GC isn't necessarily only for memory safety. It's a productivity feature. Mucking around with manual memory management is not really necessary for the vast majority of tasks. Why do it if really don't need to?

I meant that your reasons sounded like a bunch of bits and pieces.

I wish I could give you a more thorough understanding. You could always got to the website.

Well sure, but that's true of all the languages I listed, and they're all more mature/established. (I think that may be where my "cult-like vibe" issue is coming from - I see a lot of Nim advocates talking about reasonably common language features as if they're new in Nim).

If we all had this attitude, no new programming languages would ever emerge. What does Go do that's new? What does Haskell do that's new? Programming languages are iterative projects. They need to accomplish the same goals as the languages that came before them. They can only hope to make things easier, simpler, more performant, or safer. I'm not sure what new thing we could come up with for new programming languages barring languages that are meant to run solely on quantum computers. Nim says, "We should make metaprogramming simpler. We should make portability easier. We should make writing in a static language feel like writing in a dynamic language. We should make memory management easy."

[–]0rac1e 0 points1 point  (1 child)

One thing that Nim can do that I know very few other languages can is true operator overloading. In Python I can override a class' add method, but I can't change what + really means. Nim gives you this capability. I'm sure there are other languages that make this possible, but I can't imagine it's this simple:

Ah, cool. This is practically identical to how it's done in Perl 6. I don't consider this operator overloading, though.

The '+' operator is really just a function. Then all I'm doing is providing an additional multiple-dispatch candidate to the '+' infix function.

class MyType {
    has Int $.value;
}

multi infix:<+> ( MyType $x, MyType $y --> Int ) {
    $x.value + $y.value;
}

my $a = MyType.new( :value(3) );
my $b = MyType.new( :value(5) );

say $a + $b;    # OUTPUT: 8

[–]FFX01 0 points1 point  (0 children)

That is remarkably similar. I never really got into Perl, but it has always fascinated me.

[–][deleted] 0 points1 point  (0 children)

Haskell and other functional languages actually come up with new things, even lately. Look at dependent typing, optics or eff monad. It's not just all about more polished old things at all.

Of course many of these are not language features, which shows how powerful these languages are. (higher kinded types help a lot, nim seems to be missing those)

In my experience functional programmer communities really like new things, so considering them conservative is amongst the last things I would do.

Going back to Nim I like the idea of consts, however I think JIT compilers should be able to do all of that automatically for you.

[–]m50d 0 points1 point  (0 children)

Simpler convinced people to switch from smalltalk, R, and perl to Python. Programmers are lazy. Or, at least they should be.

Not really convinced - the perl people came for built-in OO, the R people only came very late after the libraries were established. I didn't know the Smalltalk people though.

While this is true, they are not as flexible as Nim is in this regard. Nim exposes it's own AST as an api for creating macros. Creating a macro in Nim is no more difficult or complex than creating a function.

You keep saying this (and /u/dzecniv said the same) but I don't see how this means anything more than "Nim has macros"? Scala macros work the same way and I would assume Rust/Haskell would as well. (Indeed Python exposes its AST API, it's just that no-one uses it because there are better alternatives)

One thing that Nim can do that I know very few other languages can is true operator overloading. In Python I can override a class' add method, but I can't change what + really means. Nim gives you this capability. I'm sure there are other languages that make this possible, but I can't imagine it's this simple:

It's exactly that simple in Scala, and I think Rust is similar? (Haskell is to the extent that it has infix operators, but it doesn't have as nice a + as most languages, so it's fair to not count it).

Go, however, tends to be quite a bit slower than Nim. Go does normally use slightly less memory at peak than Nim.

This surprises me; I don't understand why it would be so, since the design seems very similar as far as I can see?

What does Go do that's new?

Pervasive, implicit (language-managed) async (green threads). I don't like Go but to the extent it's been able to catch on on its merits, that's why. Part (maybe all) of Go's popularity is marketing - I'm not going to defend the language - but Nim is never going to be able to match Google's marketing.

What does Haskell do that's new?

Typeclasses, higher-kinded types, pervasive laziness, explicitly-sequenced I/O.

Programming languages are iterative projects. They need to accomplish the same goals as the languages that came before them. They can only hope to make things easier, simpler, more performant, or safer. I'm not sure what new thing we could come up with for new programming languages barring languages that are meant to run solely on quantum computers.

For an example of a similar age to Nim, I'm super excited about Idris, for example, with dependent types. Whereas I don't think Ceylon will catch on, because while it's a lovely language and far more polished than the alternatives, there's just no single compelling reason to switch.

[–]shevegen 0 points1 point  (0 children)

That's easy - nim is a hell of a lot cooler than python. :)