Live data from Hacker News

Things Rust shipped without

graydon2.dreamwidth.org

301–310 of 330 posts

Re: Things Rust shipped without

#301
post #248

Earlier quoted context omitted.

Dealbreaker? This just means you need to play with let bindings a little bit until they improve it at some point. (Same goes for SEME regions.)

It makes array use really awkward in my experience.

Non-lexical scope won't help with that. Remember that Rust does not allow mutable aliasing, so this code can never be allowed:

    let mut arr = [1, 2];
    let a = &mut arr[0];
    let b = &mut arr[0];
This code could be allowed:

    let mut arr = [1, 2];
    let a = &mut arr[0];
    let b = &mut arr[1];
And it gets Hard once variable indexes are involved. And since the whole point of using arrays is to get variable indexing, the Rust developers choose to only implement reborrowing for structs and tuples.

Re: Things Rust shipped without

#302

Earlier quoted context omitted.

If you want to reinterpret a float as an integer or vice versa, you can do that easily enough with Rust's unsafe functions: fn approx_invsqrt(r : f32) -> f32 { let y : f32 = unsafe { let i : i32 = std::mem::transmute(r); std::mem::transmute(0x5f375a86 - (i>>1)) }; return y*(1.5-(0.5*r*y*y)); } fn main() { println!("approx_invsqrt(2.0) = {}", approx_invsqrt(2.0)); } Result: approx_invsqrt(2.0) = 0.70693

And Rust specifies their floats to be IEEE 754, so it always works (endianness may apply though).

Seems reasonably safe to assume that i32 and f32 have the same endianness.

Re: Things Rust shipped without

#303
post #70

Earlier quoted context omitted.

That's pretty nifty, but it seems like something a really good compiler could achieve automatically. Of course I'm not sure if any compilers actually are that good.

This is not exactly how fast bytecode interpreters are implemented. There is one next step - pre-caching the jump table straight into the bytecode. And there is absolutely no way compiler can transform your ad hoc switch-based interpreter into a threaded code interpreter automatically - it is not allowed to rewrite your data willy-nilly.

Hadn't thought of that, but it sounds interesting. I guess this means that opcodes in your bytecode need to be large enough to store a pointer, this could involve some tradeoffs in terms of minimizing instructions vs fitting in the cache, but I suppose it could fall on the right side of things often enough.

Re: Things Rust shipped without

#304

Lack of `goto` is a huge disadvantage for a language with macros. Pity they did not want to provide something like `unsafe` keyword which would enable all the dirty, dangerous, high-performance stuff.

One of the things Servo (the web browser engine written in Rust) has not decided to write from scratch is a (high performance) js engine. If they did, they might have more feedback on this kind of things.

Re: Things Rust shipped without

#305

Earlier quoted context omitted.

This is not exactly how fast bytecode interpreters are implemented. There is one next step - pre-caching the jump table straight into the bytecode. And there is absolutely no way compiler can transform your ad hoc switch-based interpreter into a threaded code interpreter automatically - it is not allowed to rewrite your data willy-nilly.

Hadn't thought of that, but it sounds interesting. I guess this means that opcodes in your bytecode need to be large enough to store a pointer, this could involve some tradeoffs in terms of minimizing instructions vs fitting in the cache, but I suppose it could fall on the right side of things often enough.

32-bit opcodes are ok, even on 64-bit architectures, if you add a constant offset - see how it's done in OCaml.

Re: Things Rust shipped without

#306
post #143
post #6

> goto (not even as a reserved word) I haven't done this for a while, but once upon a graduate program I wrote a compiler from a made-up-language (MUP) to C. MUP had some strange control structures, and if C did not have "goto", it would have been a lot more difficult to implement those structures. Since then, I have always thought languages should have a "goto" statement that human-written code is not allowed to use…

I've always defended goto and gotten a lot of flak for it. As soon as I say, "I wish I had X-language had gotos", I see jaws drop. Response: "Wow, haven't you heard the news?! GOTOs are considered harmful!" I think goto should be in almost every language. It's one of the most primitive instructions, why shouldn't it be available when needed? Yes, it can be misused, just like any other feature in the language , but it…

The target of a goto statement is a specific place in code. It is not code that refers to the task you are trying to perform.

The main advantage of using higher-level languages is that you can talk about manipulations of data. Goto doesn't manipulate data, it manipulates the machine. And if you want to _really_ manipulate the machine, you're going to want more than just goto.

>Raise your hand if you plan to stop using ncurses because of how opposed to how "harmful" goto statements are.

Goto statements are not harmful to computers or to code. Ncurses isn't what is harmed by goto, nor does "using ncurses" imply any interaction with goto at all.

Muhammad Ali was a good boxer. He was Muslim. Am I to conclude that one must be Muslim to be a good boxer, now?

Yes, ncurses is a good program. Yes it uses goto. But that doesn't imply that goto is necessary to it being a good program. Or that it is even a mildy efficient way of doing well. (Especially not when there is a whole universe of alternatives.)

If you're going to defend goto (and there are reasons to do this) you should probably do so without employing such blatant logical fallacies. It's irresponsible and detracts from your point.

Re: Things Rust shipped without

#307

Earlier quoted context omitted.

Hadn't thought of that, but it sounds interesting. I guess this means that opcodes in your bytecode need to be large enough to store a pointer, this could involve some tradeoffs in terms of minimizing instructions vs fitting in the cache, but I suppose it could fall on the right side of things often enough.

32-bit opcodes are ok, even on 64-bit architectures, if you add a constant offset - see how it's done in OCaml.

An offset from the first label, or some nearby alignment point? Makes sense.

Do you have a pointer to the relevant part of OCaml's source? The whole thing is probably worth a read, but don't think I can set aside enough time for that soon, and it could take me a while to find the right part.

Re: Things Rust shipped without

#308

Earlier quoted context omitted.

32-bit opcodes are ok, even on 64-bit architectures, if you add a constant offset - see how it's done in OCaml.

An offset from the first label, or some nearby alignment point? Makes sense. Do you have a pointer to the relevant part of OCaml's source? The whole thing is probably worth a read, but don't think I can set aside enough time for that soon, and it could take me a while to find the right part.

https://github.com/ocaml/ocaml/blob/trunk/byterun/interp.c

See the "Next" macro definition.

Re: Things Rust shipped without

#309

Earlier quoted context omitted.

That's an additional pointer-chase per loop. And more function prefix / suffix work. In actuality, I suspect that it'd be optimized out - but you cannot say "you cannot do X because it relies on compiler optimizations" and replace that with Y that relies on compiler optimizations.

A function call is nothing more than putting your return address and parameters on the stack and jumping to the address of the function. By referring directly to the function's address, there's no "additional pointer chase", since calling the function already does exactly that. If you were to inline all of the perform functions in the GOTO version vs putting a macro at the end of each function, you're right that ther…

You're forgetting the overhead of popping / pushing registers. Both in terms of direct instruction overhead, and indirectly through code size and working set bloat. Which, especially for smaller functions, can be significant. It's one of the problems with a register-oriented architecture.

Sometimes this can be optimized away, but not always.

Re: Things Rust shipped without

#310
post #218

Earlier quoted context omitted.

Rust is the first language that fixes all of these things, can be used as a replacement for all of C's use cases (including ABI-stable libraries, kernels, etc.), and has a sufficient community / mindshare that you can expect libraries to exist in the language for functionality that you generally expect to find in libraries. Maybe we should be embarrassed as an industry that it took us 20 years to get there, yes.

If Rust misses 'goto', it is not suitable for translating SSA into it, which most compilers natually produce (also for LLVM, obviously). I.e., it is not suitable for being used in a compiler backend. Here, it can never fully replace C. 'goto' should not be daemonized, we know better today.

Given that the reference Rust implementation currently outputs LLVM IR, and LLVM IR is well-suited as a thing to translate compiler output to, I sort of think that you could solve that by just having new compilers use LLVM as the backend, directly. The way to make Rust support a new platform is to make LLVM support it, after all.

(But you're right, "replacement for all of C's use cases" was strictly incorrect. I'd argue that this is a bad use of C, unlike e.g. kernels or bootloaders, but that's a matter of opinion.)

Post reply on HN