Live data from Hacker News

Things Rust shipped without

graydon2.dreamwidth.org

231–240 of 330 posts

Re: Things Rust shipped without

#231
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 kernel has plenty of goto, mostly (as far as I know) to handle errors and safe resource deallocation. There is no reason to keep using GOTO if you have better mechanisms to handle these things.

Re: Things Rust shipped without

#232
post #120
post #33

Earlier quoted context omitted.

I've never had to use 'goto' in C++ except to break from a nested loop. In C++ labeled breaks would make 'goto' completely obsolete. In C it would still have use in the implementation of orderly error handling -- the pattern where you hand-implement exception handling in C by putting an on_error: label at the end of the function that is goto'd on error. The addition of some orderly construct for this in C would elimi…

> The addition of some orderly construct for this in C would eliminate that case, leaving no real role for goto there either. I like the way this is handled in Go with the defer keyword: https://blog.golang.org/defer-panic-and-recover This construct gives you most of the power of C++ RAII without the overhead. Except that you can't use it to cleanup resources after exiting an anonymous block—it strictly defers to fun…

This construct gives you most of the power of C++ RAII without the overhead.

But it leaves out the most useful part: in C++ releasing the resources is completely implicit:

    {
        std::ifstream in(fn);
        // Do something with 'in'
    } // Released
while with Go defer, you have to call explicitly for the method that you want to call. If you forget this, you still have a resource leak.

Sure, it's an improvement over languages where you have to cover every possible scope exit, but it definitely doesn't give you 'most of the power' of C++ RAII.

Re: Things Rust shipped without

#233
post #220

Earlier quoted context omitted.

Rust's CFGs are reducible with unbounded treewidth, not structured, because Rust has named exits from loops that nest arbitrarily. Most problems on reducible graphs are not easier than for general graphs, because you can always compute a loop forest (for generalized loops, not natural loops with a single entry point) and just consider a derived acyclic graph.

The structured SSA building algorithm I had in mind has a fairly simple extension that covers break, continue, and early return. It's more complicated, but still way simpler than iterated dominance frontiers. > you can always compute a loop forest It's easier to not have to.

Technically speaking, break / continue / early return are unstructured by the classical definition. The algorithm you are likely thinking of can easily be extended to handle arbitrary control-flow:

https://pp.info.uni-karlsruhe.de/uploads/publikationen/braun...

In the case of irreducible control-flow it may produce redundant cyclic phis, but those can be eliminated with a pretty simple post-pass.

Re: Things Rust shipped without

#234
post #64

Earlier quoted context omitted.

I don't know much about Rust and Rust library, so I have a question: what if I what to develop Windows only software in Rust, will I need to convert back and forth between UTF-16 and UTF-8 (or whatever Rust uses in other parts of the library)?

We have an http://doc.rust-lang.org/stable/std/ffi/struct.OsString.html to abstract over a native string in whatever encoding your platform has. Generally, things that interact with the OS use these, and they can convert to a UTF-8 String.

Suppose I'm on Linux, but I want to interact with Windows stuff. (CIFS protocol, NTFS on-disk format, disassembler for Windows executables, Wine-like program, cross-compiler, etc.)

I'll be wanting UTF-16 support. Going the other way matters too; if I'm on Windows I may need UCS-32 support.

Re: Things Rust shipped without

#235
post #97

I'd like Rust to be shipped without counterintuitive standard library function names and that book with all its style 'recommendations'. And I'd like the Rust compiler to be shipped without that non-snake case warning enabled by default. Language creators won't endear themselves to me by ranting. The problem I have with Rust is _not_ the language itself.

Yeah, that's one thing that's really putting me off looking at Rust - the possibility of it enforcing style in the future. Hanging braces style for C/C++ is rarely allowed in the coding standards I've had to use in the past for embedded and real-time stuff in the defence industry, because it can be a source of errors. Aligned opening and closing braces are much more common (in line with ADA's style).

Rust doesn't enforce style anywhere. You can turn off all style warnings at once too with `#![allow(bad_style)]` or a command line flag.

By default it just warns. That's not enforcing.

Re: Things Rust shipped without

#236

Earlier quoted context omitted.

The idea that "[u]sing a return as the last line of a function works, but is considered poor style" irks me so much. A lot of what I find appealing about Rust is that it makes so much explicit through its type system, so I don't understand the philosophy behind preferring implicit returns, especially since you could have a scenario where someone hasn't finished writing a function but it still compiles without error.

Implicit returns encourage functional style; foo.map(|x| x + 1) is so much nicer than foo.map(|x| { return x + 1; }). Once you have implicit returns in closures, you might as well have them everywhere for consistency.

compromise. Make return very short, like a unary colon ":".

Then "foo.map(|x| :x+1)" is nice. If that doesn't stand out enough for some people on a line of its own, make your editor render the unary colon line in a very bold color for you.

Re: Things Rust shipped without

#237
post #104

Earlier quoted context omitted.

Well, you generally don't, because Duff's Device isn't generally regarded as a good idea anymore, in my understanding: > It turns out that with branch predictions and the relative speed of CPU > vs. memory changing over the past decade, loop unrolling is pretty much > pointless. http://lkml.iu.edu/hypermail/linux/kernel/0008.2/0171.html

Still, there are cases where fall-through can be useful: int remaining = length % 4; switch (remaining) { case 3: h ^= (data[(length & ~3) + 2] & 0xff)

It's interesting, but a loop makes for smaller code, by a couple dozen bytes or so:

    int remaining = len % 4;

    if (remaining)
    {
        do
        {
            remaining--;
            h ^= (data[(length & ~3) + remaining] & 0xff) 
Fall-through's interesting, but at the same time, as architectures have changed, has become less useful. Self-modifying code at one time was near vital, but has fallen by the wayside, fall-through is doing much the same.

Re: Things Rust shipped without

#238

Earlier quoted context omitted.

I do not use goto in my code. What do I do wrong? :) Ok, I have to admit that I used it on C64 in the 80s. Anyways, exceptions are sort of gotos or at least they can behave that way.

No, exceptions are incomparable much harmful because they don't have destination, they just hysterically run, crashing everything on their way.

I said "sort of"...

Re: Things Rust shipped without

#239

Earlier quoted context omitted.

Implicit returns encourage functional style; foo.map(|x| x + 1) is so much nicer than foo.map(|x| { return x + 1; }). Once you have implicit returns in closures, you might as well have them everywhere for consistency.

compromise. Make return very short, like a unary colon ":". Then "foo.map(|x| :x+1)" is nice. If that doesn't stand out enough for some people on a line of its own, make your editor render the unary colon line in a very bold color for you.

That doesn't solve the fact that blocks and conditional control flow (if/else and match) are expressions and need a way to produce values.

Re: Things Rust shipped without

#240
post #216

Earlier quoted context omitted.

Rust is not a language that looks favorably on things that are easy to misuse and hard to use correctly. You can make the same argument about, say, untagged / C-style unions, which are much more common in C, but Rust doesn't have those either. I don't plan to stop using ncurses in particular, but one of the reasons I am supportive of Rust is that I would like to stop using all C software sometime in my lifetime.

Rust should have untagged unions. Obviously, ones that allow pointer abuse would be restricted to code marked unsafe. Note that a union of two pointer-containing structs is safe as long as the pointers line up, having the same type and offset in each struct.

Do you have a compelling use case? I can't imagine a use for untagged unions in Rust that isn't subsumed by other features in the language.
Post reply on HN