Announcement

Collapse
No announcement yet.

Rust For The Linux Kernel Sent Out For Review A Fourth Time

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #81
    Originally posted by shmerl View Post

    Old, rather than mature. C is also riddled with dated design problems that can't be fixed due to the need for backwards compatibility. C is good, but not good enough in the sense of language design progress. Rust is better.
    Interestingly, C in fact had such design problems that they had no choice but to break backwards compatibility. In the initial version of C, the +=, -= etc. operators were written backwards, e.g. =+, =- etc. Question: what does a=-b mean?

    They changed it and broke existing code because they finally admitted that the language was so confusing that it was almost unusable.

    There is more of course. The inane, non-type safe function parameters declaration syntax from the pre-ANSI versions ("K&R" style) - here goes another breaking change. The pointer declaration semantics that are too clever by half: many people don't realise this, but declaring int *a doesn't actually mean that a us a pointer to an int...

    Those are just a few examples for those who believe that C resulted from some deep philosophical epiphany about programming languages. It didn't, it was a quick and dirty hack to write *some* compiler that could work on and produce code for the PDP11.

    Comment


    • #82
      Originally posted by jacob View Post
      Those are just a few examples for those who believe that C resulted from some deep philosophical epiphany about programming languages. It didn't, it was a quick and dirty hack to write *some* compiler that could work on and produce code for the PDP11.
      Some major versions of C also introduce subtle differences that can be considered breaking, but still, it's not fundamentally changing some core concepts that are causing problems.

      Comment


      • #83
        Originally posted by shmerl View Post

        Old, rather than mature. C is also riddled with dated design problems that can't be fixed due to the need for backwards compatibility. C is good, but not good enough in the sense of language design progress. Rust is better.
        While I agree, knowing some of your technical background I'd like to know what design problems come to your mind. For me most are the use of outdated designs and actually not having type safety, which I agree, are only a thing due to backwards compatibility. As you can use void* pointers for interfaces, you probably should not (very simple example, but actually a real life experienced one with mathematicians designing interfaces ).
        Last edited by STiAT; 13 February 2022, 09:37 PM.

        Comment


        • #84
          Originally posted by STiAT View Post

          While I agree, knowing some of your technical background I'd like to know what design problems come to your mind. For me most are the use of outdated designs and actually not having type safety, which I agree, are only a thing due to backwards compatibility. As you can use void* pointers for interfaces, you probably should not (very simple example, but actually a real life experienced one with mathematicians designing interfaces ).
          Type safety probably is the biggest one. But lack of more powerful abstractions is also a major pain point. Rust at least attempts to provide what they call "zero cost" abstractions. Which in theory should be better than both C (not enough abstractions) and C++ (not zero cost abstractions).

          The main premise of Rust is to allow producing both performant and memory safe code, which neither C nor C++ can do both at the same time.
          Last edited by shmerl; 13 February 2022, 09:46 PM.

          Comment


          • #85
            Originally posted by shmerl View Post

            Type safety probably is the biggest one. But lack of more powerful abstractions is also a major pain point. Rust at least attempts to provide what they call "zero cost" abstractions. Which in theory should be better than both C (not enough abstractions) and C++ (not zero cost abstractions).

            The main premise of Rust is to allow producing both performant and memory safe code, which neither C nor C++ can do both at the same time.
            I think "zero cost abstractions" doesn't have the same meaning for C++ and Rust. In C++, it means that a language feature that you don't use in your code should have no cost in the resulting binary. For example if you don't use inheritance then your data structures won't have any vtables; if you use [] rather than at() to access your vectors then the resulting assembly code will be identical as if it were plain C arrays, etc. Of course that's an ideal and there are many exceptions to this.

            In Rust "zero cost" is supposed to mean that when using the language's abstractions, the resulting assembly should ideally be as efficient and optimised as if you wrote low-level code and did everything manually. That's why you can create complex operations using iterator combinators and it will (ideally) compile to the same thing as a plain old for loop in C (without unnecessary bounds checks), your code will autovectorise to take advantage of SSE, AVX etc as if you wrote it by hand using intrinsics, and so forth. Again, this is an ideal and it doesn't always work out that way, but increasingly often it does. It's the goal and the compiler gets better and better at it as time goes by.

            Comment


            • #86
              Originally posted by jacob View Post

              I think "zero cost abstractions" doesn't have the same meaning for C++ and Rust. In C++, it means that a language feature that you don't use in your code should have no cost in the resulting binary. For example if you don't use inheritance then your data structures won't have any vtables; if you use [] rather than at() to access your vectors then the resulting assembly code will be identical as if it were plain C arrays, etc. Of course that's an ideal and there are many exceptions to this.

              In Rust "zero cost" is supposed to mean that when using the language's abstractions, the resulting assembly should ideally be as efficient and optimised as if you wrote low-level code and did everything manually. That's why you can create complex operations using iterator combinators and it will (ideally) compile to the same thing as a plain old for loop in C (without unnecessary bounds checks), your code will autovectorise to take advantage of SSE, AVX etc as if you wrote it by hand using intrinsics, and so forth. Again, this is an ideal and it doesn't always work out that way, but increasingly often it does. It's the goal and the compiler gets better and better at it as time goes by.
              Yeah, the terminology is a bit mixed up, but I mean it in Rust's way. C++ doesn't attempt doing that.

              Rust also tries to avoid hidden performance overhead caused by syntax, which results in more verbose than C++ expressions sometimes (that's why there are no neat array / vector initializers in Rust for example and they prefer to use macros for that). That is also in line with their zero cost abstraction approach.
              Last edited by shmerl; 13 February 2022, 10:16 PM.

              Comment


              • #87
                Originally posted by shmerl View Post

                Yeah, the terminology is a bit mixed up, but I mean it in Rust's way. C++ doesn't attempt doing that.

                Rust also tries to avoid hidden performance overhead caused by syntax, which results in more verbose than C++ expressions sometimes (that's why there are no neat array / vector initializers in Rust for example and they prefer to use macros for that). That is also in line with their zero cost abstraction approach.
                I think the main reason Rust uses macros for vec initialisers is that because unlike C(++) its syntax doesn't allow variadic functions. That's the same reason why println is a macro and not a function. There is of course hidden cost in Rust and it doesn't always do zero-cost in the C++ sense. For example even if you don't have any "dyn trait" variables in your code, I'm not sure that it doesn't still generate vtables. It also uses fat pointers in a way that's totally transparent to the source code and that can bite you when using FFI.

                Comment


                • #88
                  Originally posted by jacob View Post

                  I think the main reason Rust uses macros for vec initialisers is that because unlike C(++) its syntax doesn't allow variadic functions.
                  I think I've seen an explanation that they could implement something like {a, b, c} syntax for initializers, but decided not to becasue that implies non trivial cost and they didn't want that to look easy in order not to be misleading. C++ adds a lot of code around that for example. But it is a much nicer syntax than what Rust is proposing to use.
                  Last edited by shmerl; 13 February 2022, 10:50 PM.

                  Comment


                  • #89
                    Originally posted by shmerl View Post

                    Type safety probably is the biggest one. But lack of more powerful abstractions is also a major pain point. Rust at least attempts to provide what they call "zero cost" abstractions. Which in theory should be better than both C (not enough abstractions) and C++ (not zero cost abstractions).

                    The main premise of Rust is to allow producing both performant and memory safe code, which neither C nor C++ can do both at the same time.
                    While I am not so sure about the "zero-cost" abstraction; I see we're on the same page there. But since no language (I know) could deliver zero cost abstraction yet, there is not much to loose. While not "zero-cost" probably a "less-cost". But I agree, we're pretty much on the same page here. Thank you for your opinion, very welcome.

                    Comment


                    • #90
                      Yeah, zero cost is a bit of a misnomer, but what they mean is trying to minimize that cost as much as they can. And in most cases it is indeed equal to not using an abstract data structure and such.

                      Comment

                      Working...
                      X