Announcement

Collapse
No announcement yet.

Even Apple Is Interested In Migrating Their C Code To Rust

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

  • rmfx
    replied
    Originally posted by r08z View Post

    You're just a bad programmer and shouldn't code in C to begin with.
    Insulting, bragging, overconfident people like you are generally the issues in those company actually.

    Leave a comment:


  • SystemCrasher
    replied
    Oh, as COVID rolls over the globe and economies everywhere begin to struggle, these overhyped infantile shithonrust kidiots would soon face far more interesting challenges than merely "let's rewrite X in Y language, because it cool buzzword, blah!" or so. Economies about to crash badly, maybe even bringing new "1929 era" on our heads, at which point business would be forced to count every penny and justify any expense, to stay, ahem, anyhow operational at all. Apple already had it hard, being forced to close factories in china and facing quite a batshit in terms of supply chains and so on.

    Needless to say, all this "let's rewrite X in Y, because Y is, basically, cool and hyped buzzword" donquixotery brings very little of "added value" compared to expenses. So best idea for apple would obviously be to fire these donquixotes ASAP and consider spending money on something that brings some added value. And I'm sorry but security isn't like that. No matter what you do, anyhow large and complicated system just not going to be secure. And merely replacing one kind of vulns with another kinds of vulns is the best you can get, as long as software still being written by humans.

    Leave a comment:


  • ssokolow
    replied
    Originally posted by cynical View Post
    Right exactly. I favor dynamic languages but in a static language you would use interfaces/traits to do the something similar. Rust made some good choices there. If I were to code in that language I would prefer a style like this over OO:
    That's actually perfectly idiomatic.

    In fact, trying to be too OO in Rust is going to cause you grief because some of the worst OO patterns don't play nicely with the borrow checker.

    Originally posted by cynical View Post
    I just like generic functions. One of my favorite things about Rust is how procedures automatically return the last expression as the result of a function. That's identical to lisp and it makes so much sense.
    Agreed. There are so many situations where, even if you're writing in a more imperative style, having an expression-oriented language makes things so much cleaner.

    Leave a comment:


  • cynical
    replied
    Originally posted by ssokolow View Post

    Ahh, yeah. I'm very glad that Python having property meant that I never learned (and then had to unlearn) a habit of pre-emptively adding accessors Just in Case™.

    (If you're not familiar with it, property enables a member that was formerly a dumb variable to be replaced with a getter and optionally a setter and/or deleter without altering the external API.)
    Interesting. No, I didn't know the Python solution to that problem.

    Originally posted by ssokolow View Post
    It's a little more difficult to do as you describe in a language with strong static-typing guarantees. You either need to implement a standard API for type casting, coercion, or conversion or you need to implement your method directly on the types.

    Again, I like Rust's approach there. (eg. Either standard-library traits like IntoIterator and Eq are used to present a consistent, familiar interface that core language constructs can make use of, or support for reinterpreting a type is implemented via traits like Deref and AsRef. For example, functions that deal with paths take an argument of type AsRef<Path> argument and Path, PathBuf, and all the string types implement AsRef<Path>.)

    On the other hand, when Rust doesn't make something seamless, there's good reason. For example, you can't use a for loop directly on a string because you need to do a method call to specify what you want to iterate. (eg. Lines? Codepoints? Codepoint indices? Bytes? ...the grapheme cluster iterator method that gets added to strings when you import the relevant trait from a third-party crate?)
    Right exactly. I favor dynamic languages but in a static language you would use interfaces/traits to do the something similar. Rust made some good choices there. If I were to code in that language I would prefer a style like this over OO:

    Code:
    fn main() {
      let vector = (1..)
          .filter(|x| x % 2 != 0)
          .take(5)
          .map(|x| x * x)
          .collect::<Vec<usize>>();
       println!("{:?}", vector);
    }
    I just like generic functions. One of my favorite things about Rust is how procedures automatically return the last expression as the result of a function. That's identical to lisp and it makes so much sense.

    Leave a comment:


  • ssokolow
    replied
    Originally posted by cynical View Post
    No you misunderstand me. I don't mean the difference between using classes and using, say, arrays of ints to represent matrices or something like that. I'm all the way in favor of classes/objects over primitives, barring performance concerns that you might get with things like boxing. I mean the difference between the OOP world of having to define methods on all your data types instead of using common functions like map, reduce, filter, etc. Let me give you a more concrete example.

    Say I write a person class in Java, with fields for the name, address, occupation, etc. Well proper design here would dictate that I add accessor methods so that I'm not directly touching the fields, so I might have a getName(), getAddress(), etc. Adding unique getters to everything kind of sucks, so a lot of IDEs automate the process for you. What do you do in Clojure, by comparison?
    Ahh, yeah. I'm very glad that Python having property meant that I never learned (and then had to unlearn) a habit of pre-emptively adding accessors Just in Case™.

    (If you're not familiar with it, property enables a member that was formerly a dumb variable to be replaced with a getter and optionally a setter and/or deleter without altering the external API.)

    Originally posted by cynical View Post
    So I don't have to write all these strangely named custom accessors. Now for methods, instead of writing something like getDistanceFromWork(), and calling it using person.getDistanceFromWork(), I could just write a (get-distance loc1 loc2) procedure and then write something like (get-distance (:work person) (:home person)), and now my get-distance procedure is portable. It's not tied to a person type. I can use it in other arbitrary locations, like another part of my application where I want to get the distance between two restaurants that happen to be popular for my user. I don't need to write something like person.getDistanceFromFavorites() or something like that, I just use the procedure I wrote with different arguments, because my procedure is no longer tied to a particular datatype.

    And under the hood my function could be doing an API call to some third party service that allows me to convert an address from a string to a set of geographical coordinates before doing subtraction to find the distance. That procedure could be useful for calculating distance in many contexts, but if I attach it to a person type, I am severely restricting its utility. It totally kills code reuse. I have other criticisms too, but that one is the worst in my eyes. Every time I interact with some new class in Java I have to lookup documentation for how to use it based on its methods, rather than just writing my own procedures based on the data contained in the fields. It's fine for people who are used to just consuming APIs and don't mind constantly guessing/learning new method names, but if you are writing your own functions, it's nice to learn a few simple tools and use them over and over again instead.
    It's a little more difficult to do as you describe in a language with strong static-typing guarantees. You either need to implement a standard API for type casting, coercion, or conversion or you need to implement your method directly on the types.

    Again, I like Rust's approach there. (eg. Either standard-library traits like IntoIterator and Eq are used to present a consistent, familiar interface that core language constructs can make use of, or support for reinterpreting a type is implemented via traits like Deref and AsRef. For example, functions that deal with paths take an argument of type AsRef<Path> argument and Path, PathBuf, and all the string types implement AsRef<Path>.)

    On the other hand, when Rust doesn't make something seamless, there's good reason. For example, you can't use a for loop directly on a string because you need to do a method call to specify what you want to iterate. (eg. Lines? Codepoints? Codepoint indices? Bytes? ...the grapheme cluster iterator method that gets added to strings when you import the relevant trait from a third-party crate?)

    Leave a comment:


  • cynical
    replied
    Originally posted by ssokolow View Post

    While I agree that making massive, overcomplicated piles of classes is overkill, you don't want to go too far in the direction of just using basic types either.

    I went through both phases and learned that lesson the hard way.

    I still have some old codebases where, while not as bad as it could have been, they define more classes than necessary.

    Likewise, I went through a phase where I was writing un-maintainable mazes of chained integer accessors using only primitive types. A custom data type or two fixed that up very nicely by adding some field names and/or methods.

    Absolutes are rarely the correct path and I like the Happy medium embodied by Rust.
    No you misunderstand me. I don't mean the difference between using classes and using, say, arrays of ints to represent matrices or something like that. I'm all the way in favor of classes/objects over primitives, barring performance concerns that you might get with things like boxing. I mean the difference between the OOP world of having to define methods on all your data types instead of using common functions like map, reduce, filter, etc. Let me give you a more concrete example.

    Say I write a person class in Java, with fields for the name, address, occupation, etc. Well proper design here would dictate that I add accessor methods so that I'm not directly touching the fields, so I might have a getName(), getAddress(), etc. Adding unique getters to everything kind of sucks, so a lot of IDEs automate the process for you. What do you do in Clojure, by comparison?

    Keywords (think symbols, which are often used as fields) act as functions, so I can represent my person as either a map or a record, and then a "getter" is just a reference to the field.

    Ex:

    Code:
    (def person
    {:name "Bob"
    :age 30
    :occupation "Software Developer"})
    
    ;; to "get" age
    (:age person) ;; -> 30
    So I don't have to write all these strangely named custom accessors. Now for methods, instead of writing something like getDistanceFromWork(), and calling it using person.getDistanceFromWork(), I could just write a (get-distance loc1 loc2) procedure and then write something like (get-distance (:work person) (:home person)), and now my get-distance procedure is portable. It's not tied to a person type. I can use it in other arbitrary locations, like another part of my application where I want to get the distance between two restaurants that happen to be popular for my user. I don't need to write something like person.getDistanceFromFavorites() or something like that, I just use the procedure I wrote with different arguments, because my procedure is no longer tied to a particular datatype.

    And under the hood my function could be doing an API call to some third party service that allows me to convert an address from a string to a set of geographical coordinates before doing subtraction to find the distance. That procedure could be useful for calculating distance in many contexts, but if I attach it to a person type, I am severely restricting its utility. It totally kills code reuse. I have other criticisms too, but that one is the worst in my eyes. Every time I interact with some new class in Java I have to lookup documentation for how to use it based on its methods, rather than just writing my own procedures based on the data contained in the fields. It's fine for people who are used to just consuming APIs and don't mind constantly guessing/learning new method names, but if you are writing your own functions, it's nice to learn a few simple tools and use them over and over again instead.

    Leave a comment:


  • ssokolow
    replied
    Originally posted by cynical View Post

    I would argue it's simpler than that. It's just passing the object you are working with as the first argument to every function.

    It's not true that thinking it's a mistake is a sign of not understanding OOP. I mean I don't hate OOP by any means, but there are great arguments against it. To me personally, the main problem is the "API explosion" you get with all these user defined types and methods. I'm a functional programmer who prefers lisp. You know what's nice about that? I can use the exact same functions with all my data types, because I am operating on simple data structures that use the same interfaces instead of re-inventing methods for each custom type.

    Before I learned Java, I didn't really understand why there was such a focus on heavy IDEs like Eclipse. Now I get it. It's because remembering the API for thousands of types is not possible, and autocomplete is a blessing there. In a functional language (or using a language like JS in a functional style), you can learn 50 functions and use those same tools everywhere, so writing in a simple text editor becomes feasible.
    While I agree that making massive, overcomplicated piles of classes is overkill, you don't want to go too far in the direction of just using basic types either.

    I went through both phases and learned that lesson the hard way.

    I still have some old codebases where, while not as bad as it could have been, they define more classes than necessary.

    Likewise, I went through a phase where I was writing un-maintainable mazes of chained integer accessors using only primitive types. A custom data type or two fixed that up very nicely by adding some field names and/or methods.

    Absolutes are rarely the correct path and I like the Happy medium embodied by Rust.

    Type inference is allowed within methods, but you must specify the method signatures explicitly.

    Types implement various common traits so they share a familiar API, but things like String, OSString, and Path uphold different invariants despite all ultimately being single-element struct wrappers around Vec<u8>, so it's a compile-time error to mix them up without explicit conversion.

    Likewise, compile-time verification of units of measure is a good idea. meters + feet should be a compile-time error.

    Leave a comment:


  • cynical
    replied
    Originally posted by Luke_Wolf View Post
    Those who say "OOP is a mistake" either misunderstand OOP and blame OOP for shitty programmers who also don't understand OOP existing or they learned to program in the 70s and 80s and are clinging as hard as they can to C to try to remain relevant.

    The irony being that OOP is an extraordinarily simple concept. All OOP really is is architecting your program to be a box of things that have adjectives and can verb each other, and this box of things is attempting to closely model real world objects, processes, or concepts. That's it. Nothing more. Nothing less. The rest is all implementation details, and things that make it easier to achieve creating said models.
    I would argue it's simpler than that. It's just passing the object you are working with as the first argument to every function.

    It's not true that thinking it's a mistake is a sign of not understanding OOP. I mean I don't hate OOP by any means, but there are great arguments against it. To me personally, the main problem is the "API explosion" you get with all these user defined types and methods. I'm a functional programmer who prefers lisp. You know what's nice about that? I can use the exact same functions with all my data types, because I am operating on simple data structures that use the same interfaces instead of re-inventing methods for each custom type.

    Before I learned Java, I didn't really understand why there was such a focus on heavy IDEs like Eclipse. Now I get it. It's because remembering the API for thousands of types is not possible, and autocomplete is a blessing there. In a functional language (or using a language like JS in a functional style), you can learn 50 functions and use those same tools everywhere, so writing in a simple text editor becomes feasible.

    Leave a comment:


  • Michael
    replied
    Originally posted by Saurbh01Soni View Post
    Just want to ask the source of the image.
    The source of the image in the article ? I took the picture.

    Leave a comment:


  • Saurbh01Soni
    replied
    Just want to ask the source of the image.

    Leave a comment:

Working...
X