Live data from Hacker News

Things Rust shipped without

graydon2.dreamwidth.org

241–250 of 330 posts

Re: Things Rust shipped without

#242
post #151

Earlier quoted context omitted.

Funny, co-routines have been recently added to C++ and they work wonders. D has fibers which are used extensively and once again, it's a highly desired feature. Go is kind of the poster boy for coroutines and I doubt anyone claims that it doesn't provide many advantages. To be honest it seems to me like your explanation is an attempt to downplay just how nice fibers/coroutines are rather than acknowledge their utilit…

No, his explanation is the few-line summary of years of failed experiments in userspace M:N threading. Userspace is not equipped to make reasonable scheduling decisions that provide any significant performance advantage, and library/language runtime control of M thread register/stack contexts on top of N kernel threads plays absolute havoc with most operating system's standard libraries. Go works around this by expli…

You are correct the current proposed C++ coroutines are vastly different then M:N userspace threading. The allocation differences are drastic, and unlike Go they play nicely with system libraries.

Re: Things Rust shipped without

#244
post #68
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…

A bitecode interpreter is another place where it's nice to have gotos. Here's the base code without gotos: typedef enum { ADD, MUL, ..., END } opcode; void run() { opcode ins; while (1) { ins = fetch_next_inst(); switch (ins) { case ADD: perform_addition(); break; case MUL: perform_multiplication(); break; ... case END: wrap_up(); return; } } } You have 3 jumps on each loop. From the break to the end of the loop, the…

I really dislike 'clever' code like this, even when speed is paramount you will find that by obscuring the flow you make it harder, not easier to really optimize the code.

Over time it tends to evolve into ever messier and harder to understand versions of the initial run after which a future maintainer will end up losing sleep and or hair chasing some production bug.

Consider this (slower!) much clearer alternative, and consider too that if you need to eliminate one goto for speed reasons that you're most likely doing something wrong:

  typedef enum { ADD, MUL, ..., END } opcode;

  int process_instruction(opcode ins) {

      switch (ins) {
        case ADD:
          perform_addition();
          break;

        case MUL:
          perform_multiplication();
          break;
        ...
        case END:
          return FALSE;
      }

      return TRUE;
  }

  void run() {

    do {
    } while (process_instruction(fetch_next_instruction());

    wrap_up();
  }
That's a whole function call overhead (but you can eliminate that with an 'inline'), it's easier to test and much easier to follow what it does.

It would be interesting to see what the actual difference is in speed when comparing those two versions, I suspect that the contents of 'perform_addition' and 'perform_multiplication' are going to be the key here, not whether or not the loop uses a short-cut or an instruction (or two) less. Oh, and you could have eliminated that 'ins' variable.

Re: Things Rust shipped without

#245
post #90
post #68

Earlier quoted context omitted.

A bitecode interpreter is another place where it's nice to have gotos. Here's the base code without gotos: typedef enum { ADD, MUL, ..., END } opcode; void run() { opcode ins; while (1) { ins = fetch_next_inst(); switch (ins) { case ADD: perform_addition(); break; case MUL: perform_multiplication(); break; ... case END: wrap_up(); return; } } } You have 3 jumps on each loop. From the break to the end of the loop, the…

~20 years of using various combinations of C and C++, and i never knew you could take the address of a label! reminds me of computed GOSUBs from my basic days :)

Before you use such constructs make sure your team lead or boss is ok with it, it's incompatible with many compilers and ugly to boot. This is the kind of code that gives C its bad reputation.

Re: Things Rust shipped without

#246
post #59
post #58

What is wrong with UTF-16 support?

It's an encoding that isn't good at anything: it's neither ASCII-compatible (like UTF-8), nor fixed-length (like UTF-32), but because most characters require only 2 bytes, developers frequently assume that none require more, leading to bugs when a character eventually is represented by 4 bytes.

UTF-32 is not good for anything either, easy access to codepoints is just as useless as access to UTF-8 bytes. Any meaningful operation on text (even counting number of characters) requires parsing grapheme clusters, which have variable length regardless of what encoding is used.

Re: Things Rust shipped without

#247
post #82

Earlier quoted context omitted.

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

A foolish consistency is the hobgoblin of little minds. Sometimes a variation in rules allows for more clarity -- one could set their editor to make return a different color, for example, making it easier to glance at program flow. Then again, I'd argue that closures should allow returns too, like they do in C#. I'm an adamant supporter of the explicit camp -- when you have to debug things at 3 in the morning, someti…

I find the way it works in scala very nice - a block is just an expression that evaluates to the last statement in the block, and idiomatic code never uses "return" anywhere. Even e.g. a function definition, you can replace the block with a single expression if it's more convenient. I agree with being explicit but I don't think return actually makes things any more explicit (if you're talking about an editor highlighting, the editor knows which line is the value of the block, with or without a "return") - rather it's just syntactic ceremony. It's surprising how much difference having very low-overhead closures makes - you can make so much of your program simpler, because it's not a problem if a caller needs to make a slight modification to something.

Re: Things Rust shipped without

#248
post #147

Earlier quoted context omitted.

Non-lexical lifetimes/borrows. This is a dealbreaker IMO.

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.

Re: Things Rust shipped without

#249
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…

C's goto has a bad rep it only partially deserves, however I can't agree that it should be in every language. I use it fairly frequently, but virtually all the uses are about cleanup after error. I like that it requires unique label for identification, as it allows for language-enforced documentation. But my gotos always go "down" the source code, never "up. Through goto I can basically setup an error-condition code flow for every function, with multiple conditional entry points into that flow and if there was another language feature that allowed just this particular usage in cleanup, without multiple nested scopes and with clear labelling, then I would see no reason for keeping goto. Throughout the years we developed a way to neatly use an unsafe feature, but it's always better to have such things enforced by language, not by tradition.

Re: Things Rust shipped without

#250
post #218

I'm sorry, but I have a hard time being impressed by any of those. They're all just fixing things that were busted in C. I mean good for Rust, but C is a pretty low bar. Does any language created in the last 20 years make those same mistakes?

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.

Post reply on HN