Live data from Hacker News

Things Rust shipped without

graydon2.dreamwidth.org

101–110 of 330 posts

Re: Things Rust shipped without

#102
post #60
post #12

What about things that Rust shipped without that should have been included?

Coroutines, Go style.

M:N threads didn't work for Rust, and they don't have that many advantages anyway even in languages where they do work. There has been a lot of discussion on this over the years and this has been the conclusion everyone came to.

Re: Things Rust shipped without

#103
post #82

Earlier quoted context omitted.

Why "might as well"? Things can be optimal in some places and suboptimal elsewhere.

Consistency is valuable. If some blocks have different rules to other blocks that's a real downside.

That's true, but they're so syntactically different that I can't imagine a scenario where someone is asking whether it's closures or functions that you're supposed to use return statements in.

Re: Things Rust shipped without

#104

How does one accomplish loop-unrolling as in Duff's Device in rust, if case statements do not fall through?

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) 

Re: Things Rust shipped without

#105
post #51

Earlier quoted context omitted.

I don't think I've written a goto since the 1970s, and I've written a lot of code since then. If you need to bail out of something in the middle, make it a function.

As mentioned above, in C goto is often useful for error handling (where you need to free some resources before exiting the function). It's way more convenient and readable to write freeing code once and jump to it instead of having multiple return exits and duplicate the code before every single one of them.

What the parent said still applies in your case. You just make a wrapper function that does the cleanup. I have used this pattern many times:

  static int foo_impl(int arg, int **resource1, int **resource2) {
    *resource1 = (int *)malloc(sizeof(**resource1));
    if (*resource1 == NULL) return EXIT_FAILURE;
    /* Do something with resource1 (omitted)... */
    *resource2 = (int *)malloc(sizeof(**resource2));
    if (*resource2 == NULL) return EXIT_FAILURE;
    /* Do something with resource1 and resource2 (e.g.,
       stick them in a global hash table as key/value pairs,
       or whatever, omitted)... */
    return EXIT_SUCCESS;
  }

  int foo(int arg) {
    int *resource1;
    int *resource2;
    int ret;
    resource1 = resource2 = NULL;
    ret = foo_impl(arg, &resource1, &resource2);
    if (ret != EXIT_SUCCESS) {
      free(resource2);
      free(resource1);
    }
    return ret;
  }
The advantages are that it makes it very explicit which resources need to be cleaned up (making it easier to review to be sure you haven't forgotten one, or forgotten to initialize one, because they're in a nice list), and it's harder to screw up the control flow. You can't get out of the function without passing by the clean-up code, and you can't accidentally fall into the clean-up code without explicitly returning an error.

Re: Things Rust shipped without

#107
post #54

Earlier quoted context omitted.

rustfmt (currently in development) follows this principle.

Please don't make it an option. Use one format to rule them all, as with "gofmt". I don't care what it is, but pick something and standardize.

I'm not working on rustfmt but my understanding is that its output is going to be configurable.

Every language carries with it a culture. The culture of Go is one which allows for gofmt to define one true style and refuse to deviate, just as it allows the language designers to refrain from adding generics.

The culture of Rust is not like that, for several reasons. For one, the Rust community loves a good bikeshed. For two, the syntax of Rust is more complicated than Go, and includes situations (match statements & where clauses come to mind) in which people are just going to want to different things.

I know the advantages of one true style - everyone's heard the arguments - and there's a sane, median default as the official style guide, which will be rustfmt's default output. That seems like a good compromise.

Re: Things Rust shipped without

#108
post #3

Earlier quoted context omitted.

union foo { int x; float y; }; union foo bad; bad.x = 100; printf("%f\n", bad.y); // undefined behavior (though usually works)

Which is actually a useful feature in some obscure optimizations, like this fast (approximate) square root: float half_r=r*0.5F; union { float y; int32_t i; }; y=r; i=0x5f375a86-(i>>1); y=y*(1.5F-(half_r*y*y)); return y;

That hasn't been an optimization for 15 years now. Fast approximate inverse square root is a builtin operation on most FPUs-- on x86, it's RSQRTSS, which tends to be the same cost as a floating point multiply. (for Haswell, it has a 5 cycle latency, and 1 cycle reciprocal throughput)

Re: Things Rust shipped without

#109
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)

https://github.com/pythonesque/fallthrough can emulate the fallthrough style if you really, really want to have it. It seems like it hasn't been updated in a while, though.

Re: Things Rust shipped without

#110

Earlier quoted context omitted.

> Why should I even care about stuff like this being "considered poor style" by the creators of Rust? Maybe you are writing code for the Rust standard library, where following the core projects style recommendations would be important for consistency. Maybe you don't want to start from scratch coming up with your own style, and want a decent starting point from which you can vary as your team figures out what does/do…

Style recommendations are great and if I was writing code for the standard library, I would certainly follow them. But they don't simply recommend their style. "We recommend doing this like that" is very different from "Doing this that way is considered poor style". That sounds like their recommendations were objective facts and you shouldn't do anything else, even if that worked better for you and the majority of ot…

> That sounds like their recommendations were objective facts

On the one hand, it is an objective fact that it is considered, by the authors, poor style.

On the other hand, that it is "considered" anything is an explicit (not merely implicit) statement that it is subjective (and "poor style" -- or good style, for that matter is inherently subjective in any case.) So, characterizing that language as making it sound "like their recommendations are objective facts" seems quite bizarre.

Post reply on HN