Live data from Hacker News

Rust for C++ programmers – part 3: primitive types and operators

featherweightmusings.blogspot.com

61–68 of 68 posts

Re: Rust for C++ programmers – part 3: primitive types and operators

#61

Earlier quoted context omitted.

It's not that uncommon to want to recover from NPEs in a webapp environment. You want your thread of execution to error out, return a 500, and rollback whatever db changes it's made, but you want the webapp as a whole to keep running.

And this is precisely what task failure in Rust lets you do. Requests run in tasks, if the task fails, show an error message and make a new task for the next request.

Yes, sorry - I wasn't meaning to state that rust is bad in this regard. Just addressing the point of catching NPEs and so on.

Re: Rust for C++ programmers – part 3: primitive types and operators

#62
post #33

Having been the victim of a fun Javascript bug recently (something like ("1" + 10)*2), I must say that I agree that type coercion is the wrong thing to do 99% of the time (probably with the exception of attempting to divide integers).

99% of such bugs can be avoided in a weakly typed language by simply having the string concatenation operator different from the "+" operator (PHP has the "." operator for this, VisualBasic has "&" ...Haskell has "++" ) ...yet Javascript, Python and Ruby seem to stubbornly avoid this simple way of achieving some sort of sanity (and yeas on this one PHP is above Python and Javascript!). Also, having " " also work for…

Haskell is a more complex case. (++) is the list concatenation operator, eg: [1,2,3,4] = [1,2} ++ [3,4]. While the default String type is nothing more than a linked list of Unicode codepoints, it's notoriously inefficient. The preferred way of representing strings is usually Data.Text, which being a monoid, supports for concatenation. However, if you only kept the addition operation for number, you could perfectly well do 1 2 and obtain 3 (you can actually do that with Sum 1 Sum 2, obtaining Sum 3 as a result - wrapping with Sum is necessary due to the fact that numbers are also a monoid under multiplication). What would save you from a runtime error is the fact that the monoid concatenation operator expects its two parameters to have the same datatype.

Re: Rust for C++ programmers – part 3: primitive types and operators

#63
post #48

I understand that there is probably a performance motivation for having int/uint having machine-dependent sizes. However, it seems to me that having different sizes on different platforms is a potential security hazard if the programmer doesn't think of this. It also gives rise to porting bugs. Isn't the idea of rust to make a securer language than C++? I would have thought mandating 32 or 64 bit for int/uint would m…

It's not out of concern of performance.

The idea was in fact to reduce correctness gotchas; ints are often used for indexing into arrays, and you want the size of the integer to reflect the maximum size of an array on your platform.

What kind of security issues did you have in mind? Integer overflow can be a problem, but it is usually a memory safety issue, which Rust doesn't have due to bounds checks and iterators.

Re: Rust for C++ programmers – part 3: primitive types and operators

#64
post #48

I understand that there is probably a performance motivation for having int/uint having machine-dependent sizes. However, it seems to me that having different sizes on different platforms is a potential security hazard if the programmer doesn't think of this. It also gives rise to porting bugs. Isn't the idea of rust to make a securer language than C++? I would have thought mandating 32 or 64 bit for int/uint would m…

It's not out of concern of performance. The idea was in fact to reduce correctness gotchas; ints are often used for indexing into arrays, and you want the size of the integer to reflect the maximum size of an array on your platform. What kind of security issues did you have in mind? Integer overflow can be a problem, but it is usually a memory safety issue, which Rust doesn't have due to bounds checks and iterators.

Their use as index to arrays sounds reasonable. However in this case it may be wiser to give them less friendly names than those for the 32-bit and 64-bit counterparts. To not have portability issues, it is important that the programmer understands when int and uint should be used (index to arrays, the sizes of which could be machine dependent) and when specified-size integer types (when representing application-specific data).

Re: Rust for C++ programmers – part 3: primitive types and operators

#65
post #64

Earlier quoted context omitted.

It's not out of concern of performance. The idea was in fact to reduce correctness gotchas; ints are often used for indexing into arrays, and you want the size of the integer to reflect the maximum size of an array on your platform. What kind of security issues did you have in mind? Integer overflow can be a problem, but it is usually a memory safety issue, which Rust doesn't have due to bounds checks and iterators.

Their use as index to arrays sounds reasonable. However in this case it may be wiser to give them less friendly names than those for the 32-bit and 64-bit counterparts. To not have portability issues, it is important that the programmer understands when int and uint should be used (index to arrays, the sizes of which could be machine dependent) and when specified-size integer types (when representing application-spec…

Yeah, we considered naming them intptr_t and uintptr_t, but the "use an int to index an array" is so ingrained into programmers' collective consciousnesses that we decided it was pretty futile to go against the grain here.

Re: Rust for C++ programmers – part 3: primitive types and operators

#66

Having been the victim of a fun Javascript bug recently (something like ("1" + 10)*2), I must say that I agree that type coercion is the wrong thing to do 99% of the time (probably with the exception of attempting to divide integers).

I think too that integer division should by default yield floating-point. And likewise for uint subtraction, which should yield int and not uint by default. The programmer may appropriately cast to uint if she knows that the result will not be negative.

Re: Rust for C++ programmers – part 3: primitive types and operators

#67
post #64

Earlier quoted context omitted.

Their use as index to arrays sounds reasonable. However in this case it may be wiser to give them less friendly names than those for the 32-bit and 64-bit counterparts. To not have portability issues, it is important that the programmer understands when int and uint should be used (index to arrays, the sizes of which could be machine dependent) and when specified-size integer types (when representing application-spec…

Yeah, we considered naming them intptr_t and uintptr_t, but the "use an int to index an array" is so ingrained into programmers' collective consciousnesses that we decided it was pretty futile to go against the grain here.

I don't really buy that reasoning. :-) If the goal is not to clean up bad things, we may just stay with C++.

When a new language comes and the programmer is already having an intention to learn something new, probably is working on a new project, this state is the best opportunity for the cleanup. Once the language matures, legacy codebases become rampant, that opportunity is gone forever with that language.

Did you consider naming the type something like 'index' itself, if that is the predominant good use-case for the type?

Re: Rust for C++ programmers – part 3: primitive types and operators

#68
post #48

I understand that there is probably a performance motivation for having int/uint having machine-dependent sizes. However, it seems to me that having different sizes on different platforms is a potential security hazard if the programmer doesn't think of this. It also gives rise to porting bugs. Isn't the idea of rust to make a securer language than C++? I would have thought mandating 32 or 64 bit for int/uint would m…

It's not out of concern of performance. The idea was in fact to reduce correctness gotchas; ints are often used for indexing into arrays, and you want the size of the integer to reflect the maximum size of an array on your platform. What kind of security issues did you have in mind? Integer overflow can be a problem, but it is usually a memory safety issue, which Rust doesn't have due to bounds checks and iterators.

I'm not familiar with the bounds checks in rust, so that sounds a bit more reassuring. However, I could imagine logic errors if people assume they have a certain size, but they don't, as I assume you don't trap wrapping and so on.

If they're intended for indexing arrays, I would have given then a name to reflect that, and discouraged people from mixing them with normal integers for doing arithmetic with. Perhaps forcing people to convert integers to array indices would be good. I try to use size_t and friends when programming C++.

Post reply on HN