Live data from Hacker News

Nim binary size from 160 KB to 150 Bytes

hookrace.net

21–30 of 69 posts

Re: Nim binary size from 160 KB to 150 Bytes

#21
post #19

Earlier quoted context omitted.

As for null in general, you can hear it from the horse's mouth here: http://www.infoq.com/presentations/Null-References-The-Billi... There are a number of ways to approach this topic, so I'll just give you one: in languages with more advanced static type systems, you try to encode as much semantic information as possible in the type. As you've said, the idea of null can be useful, so it deserves a place in the type s…

I agree the concept of 'non-nil' vars is very useful (and we have that in Nim), but I'm not entirely convinced by the rest of that argument. Namely, I don't agree that nil is rare enough to justify the verbosity Rust uses for it. Non-nil vars may be seen more often, but that doesn't mean nil vars aren't also often used, either. In Nim, both nil and non-nil vars are at roughly the same reach.. while in Rust non-nil va…

Fair enough. My argument here is more general than Rust itself, it's relevant to all languages with an Option type and no null. The verbosity can of course vary by language.

Re: Nim binary size from 160 KB to 150 Bytes

#22
post #13
post #5

Today I looked at Nim in a bit more depth because it keeps popping up. I have a slightly uncomfortable feeling about it that I hope is unfounded! To me it looks like it makes the unsafety of c more accessible because of better tooling and nicer syntax. Looking at e.g. [1] there are still pointers, null-pointers etc, just like in c. So now you have a language that looks superficially simple but is actually very danger…

So Rust has some cool safety features, especially for concurrent code. But, and perhaps I'm just uninformed, I never really understood the safety benefit of Rust's 'never nil' design. Nil is a useful modelling tool, even in Rust where it exists via Option /None, correct? Perhaps by forcing you to be extremely explicit (and enforcing `match` always handles all conditions) you gain some arguable safety, but at what cos…

> Nil is a useful modelling tool, even in Rust where it exists via Option/None, correct?

It's not that null is not useful. It's that most pointers can never be null, so nullability is the wrong default. And it is useful for the compiler to force you to handle the case in which pointers are null.

> Perhaps by forcing you to be extremely explicit (and enforcing `match` always handles all conditions) you gain some arguable safety, but at what cost?

There's basically no downside to having no null pointers. With constructs like Option::map the code is usually even less verbose than the equivalent code with null.

> It's certainly not easier to use and reason about, IMO.

You never have to worry about your program failing whenever you type "." or "∗". With null, the semantics of the language are that an exception can be thrown [1] whenever those constructs are invoked. That's pretty much objectively easier to reason about.

> It seems to me the design was chosen more as a way to ensure memory lifetime could be better predicted by the compiler rather than any strong argument for safety

Huh? Lifetimes are totally independent. We could have had null pointers with the lifetime system (and there were languages like Cyclone that had both). The system exists precisely because of safety.

We also get some really nice optimizations out of it that are impossible to get in C. All pointers in Rust are dereferenceable per the LLVM definition, which opens up some really neat optimizations like loop invariant code motion on loads.

> in my experience nil-deref errors are rarely a painful thing. They happen often, but are also fixed quickly.

Not in my experience. They show up in production all the time.

[1]: Or you could do what Nim does, and make dereferencing null undefined behavior instead of guaranteeing that an exception is thrown, but that strikes me as worse than what Java does.

Re: Nim binary size from 160 KB to 150 Bytes

#23
post #20

Earlier quoted context omitted.

Rust isn't putting a lot of specific effort into embedded, but we already work on many embedded platforms. As the language matures, I expect that support to grow.

Embedded and especially bare-metal applications really are 2nd class citizens in the rust ecosystem though. You basically can't use cargo (or at least not without a whole bunch of hacks) and many important features for low-level code are still gated and won't be available for 1.0. I think it's a bit of a shame because that's basically the #1 differentiator with languages like Go or Java as far as I'm concerned. But b…

> You basically can't use cargo (or at least not without a whole bunch of hacks) and many important features for low-level code are still gated and won't be available for 1.0.

Yup, both of these things are true. This is what I meant by increased support: we have a long way to go to make it as nice to use, and on a stable release of Rust. But the fundamentals are in place.

Re: Nim binary size from 160 KB to 150 Bytes

#24

This seems mostly useful in highly constrained embedded environments (AVR, MSP430, ARM M0, PIC etc.) Unfortunately it seems like none of these "modern" system languages (Nim, Rust) seem to be putting too much effort towards embedded platforms :(

You're right that most Nim users don't do it, but you should be able to use Nim for embedded environments as a replacement for C.:

- http://nim-lang.org/nimc.html#nim-for-embedded-systems

- https://github.com/sirlantis/pebble-nim

Re: Nim binary size from 160 KB to 150 Bytes

#25
post #19

Earlier quoted context omitted.

As for null in general, you can hear it from the horse's mouth here: http://www.infoq.com/presentations/Null-References-The-Billi... There are a number of ways to approach this topic, so I'll just give you one: in languages with more advanced static type systems, you try to encode as much semantic information as possible in the type. As you've said, the idea of null can be useful, so it deserves a place in the type s…

I agree the concept of 'non-nil' vars is very useful (and we have that in Nim), but I'm not entirely convinced by the rest of that argument. Namely, I don't agree that nil is rare enough to justify the verbosity Rust uses for it. Non-nil vars may be seen more often, but that doesn't mean nil vars aren't also often used, either. In Nim, both nil and non-nil vars are at roughly the same reach.. while in Rust non-nil va…

> Namely, I don't agree that nil is rare enough to justify the verbosity Rust uses for it. Non-nil vars may be seen more often, but that doesn't mean nil vars aren't also often used, either.

It's not verbose. "Option" is 6 characters. ".map" is 4.

> In Nim, both nil and non-nil vars are at roughly the same reach.. while in Rust non-nil vars are significantly easier work with.

Option values are really easy to work with. Just use map or unwrap if you don't care about handling the null case. If you do care about handling it (which you should, after all!) the code using "if let" is the same as the equivalent "if foo == null".

Re: Nim binary size from 160 KB to 150 Bytes

#26
post #13
post #5

Today I looked at Nim in a bit more depth because it keeps popping up. I have a slightly uncomfortable feeling about it that I hope is unfounded! To me it looks like it makes the unsafety of c more accessible because of better tooling and nicer syntax. Looking at e.g. [1] there are still pointers, null-pointers etc, just like in c. So now you have a language that looks superficially simple but is actually very danger…

So Rust has some cool safety features, especially for concurrent code. But, and perhaps I'm just uninformed, I never really understood the safety benefit of Rust's 'never nil' design. Nil is a useful modelling tool, even in Rust where it exists via Option /None, correct? Perhaps by forcing you to be extremely explicit (and enforcing `match` always handles all conditions) you gain some arguable safety, but at what cos…

> Nil is a useful modelling tool, even in Rust where it exists via Option/None, correct?

Yes. So? A lot of things are useful modelling tools, but that doesn't mean you necessarily want to include them in every reference-like type. A tuple of two things is useful modelling tool; should that then be infused into every type? A "either value or error" is a useful type; should that be infused into every type?

No? Then what makes "Either something or nothing" so special?

Re: Nim binary size from 160 KB to 150 Bytes

#27
post #19

Earlier quoted context omitted.

As for null in general, you can hear it from the horse's mouth here: http://www.infoq.com/presentations/Null-References-The-Billi... There are a number of ways to approach this topic, so I'll just give you one: in languages with more advanced static type systems, you try to encode as much semantic information as possible in the type. As you've said, the idea of null can be useful, so it deserves a place in the type s…

I agree the concept of 'non-nil' vars is very useful (and we have that in Nim), but I'm not entirely convinced by the rest of that argument. Namely, I don't agree that nil is rare enough to justify the verbosity Rust uses for it. Non-nil vars may be seen more often, but that doesn't mean nil vars aren't also often used, either. In Nim, both nil and non-nil vars are at roughly the same reach.. while in Rust non-nil va…

What's the rust name/syntax for non-nil vars?

Re: Nim binary size from 160 KB to 150 Bytes

#28
post #27
post #19

Earlier quoted context omitted.

I agree the concept of 'non-nil' vars is very useful (and we have that in Nim), but I'm not entirely convinced by the rest of that argument. Namely, I don't agree that nil is rare enough to justify the verbosity Rust uses for it. Non-nil vars may be seen more often, but that doesn't mean nil vars aren't also often used, either. In Nim, both nil and non-nil vars are at roughly the same reach.. while in Rust non-nil va…

What's the rust name/syntax for non-nil vars?

    let foo = 5; // cannot be null
    let bar = Some(5); // technically also can't be null, but could be None
                       // instead of Some(val)
`foo` has the type `i32` here, and `bar` has the type `Option`.

Re: Nim binary size from 160 KB to 150 Bytes

#29

This seems mostly useful in highly constrained embedded environments (AVR, MSP430, ARM M0, PIC etc.) Unfortunately it seems like none of these "modern" system languages (Nim, Rust) seem to be putting too much effort towards embedded platforms :(

Also useful for reasonable computing going forward. See more details: https://twitter.com/lix/status/589171043010412544

Re: Nim binary size from 160 KB to 150 Bytes

#30
post #13

Earlier quoted context omitted.

So Rust has some cool safety features, especially for concurrent code. But, and perhaps I'm just uninformed, I never really understood the safety benefit of Rust's 'never nil' design. Nil is a useful modelling tool, even in Rust where it exists via Option /None, correct? Perhaps by forcing you to be extremely explicit (and enforcing `match` always handles all conditions) you gain some arguable safety, but at what cos…

It's not so much about "never nil" , but rather "never accidentally null" . Rust's compiler prevents you from moving data into a method which then nulls it out, leaving a dangling pointer in the calling code. 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. Rust will just refuse to comp…

> 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 :)

Post reply on HN