Hacker News new | past | comments | ask | show | jobs | submit login

> Rust's compiler prevents you from moving data into a method which then nulls it out

Just for clarity, we have this in Nim too, eg:

  type
    Foo = ref object
    Bar = object
      val: Foo not nil
  let
    f = Bar() # Error, 'val' must be set
  
  proc foobar(f: Foo not nil): Foo not nil =
    return nil # Error, can't return nil
  
  foobar(nil) # Error, can't pass nil
> At best this dangling pointer will look at garbage and cause a crash or undefined behavior. At worst, it will look at other, actively-used memory and cause a security vulnerability.

In C/C++, yes, but this isn't so applicable to Nim where we have GCed references and 'not nil' constraints.

> If you use iterators in Rust, you never need to worry about out of bounds errors

Well I was not talking about iterating through a list, but rather maintaining arbitrary indexes to a mutable list. Eg, a Sprite which contains a index to a Texture array. In that scenario it's just as easy to miscalculate and crash your program via a bounds-checking error as it is to crash by nil-deref.

> To offer a counter-viewpoint, I find that Option<> (and Result<>) are very easy to reason about..

It's good that Rust works for you, truly. And like I said in another post, I agree Rust's design here may be better for some domains. However, Nim's design still feels more elegant and straight-forward to me. Luckily, we both get a powerful language that suits us, regardless of which one we prefer :)




Oh, sorry, I should have been clearer: I wasn't trying to disparage Nim at all (it's on my list of languages to play with). I was just clearing up some points about Rust :)

Edit:

> Well I was not talking about iterating through a list, but rather maintaining arbitrary indexes to a mutable list. Eg, a Sprite which contains a index to a Texture array. In that scenario it's just as easy to miscalculate and crash your program via a bounds-checking error as it is to crash by nil-deref.

The solution here is to just use a reference instead of an arbitrary index. If you hand out references you can lean on the compiler to enforce memory safety -- the compiler won't let you access data that is no longer alive, won't let you accidentally share across thread boundaries if you don't explicitly want that, etc. And if that was a shared mutable list, it's doubly important to let the compiler help you reason about it, since shared, mutable state is the main source of data races.

This is one of those cases where leveraging the compiler allows you to write better, safer code.


No worries. I also wasn't implying you where trying to discourage Nim, and I hope my post didn't come off as accusatory. Cheers!

EDIT:

> The solution here is to just use a reference instead of an arbitrary index.

Ah, sorry I should have said "mutable Texture array". In that case Rust's borrow-checking will 'freeze' the array, preventing Textures from ever being changed during the lifetime of your Sprites. So you're left with either Option<> or indexing as a solution, each with it's own merits, but neither as.. practical as nilable GCed references, IMO (again, just my opinion.. others seem to find it easy enough).


Out of curiosity: How do you convert from a nilable `Foo` to a `Foo not nil`? As in, what do you do if you have a function maybe returning a `Foo` and want to pass its value to a function taking `Foo not nil`?


You prove to the compiler that the nilable var is not-nil via if statement. Eg:

  proc foobar(f:Foo not nil) =
    discard
  
  let f = Foo() # nilable ref
  let b: Foo not nil = f # Error, can't prove 'f' is not nil

  if f != nil:
    let b: Foo not nil = f # can assign non-nil vars to 'f'
    foobar(f) # or can pass 'f' directly


Ah, good to know. So Nim does static analysis on conditionals where Rust would use an explicit pattern match to get at the contained value.

Might be a good example for http://nim-lang.org/manual.html#not-nil-annotation




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: