No announcement yet.

Rust-Written Redox OS 0.8 Released With i686 Support, Audio & Multi-Display Working

  • Filter
  • Time
  • Show
Clear All
new posts

  • Originally posted by xfcemint View Post
    - "requiring type constraints on generics" - now I'm getting a bit suspicious. I don't want "generics" implemented with "type deletions", as in Java, I want generics to be like templates (i.e. automatically multiplicated code, depending on types). On the other hand, "type deletion" in Java is kind-of acceptable to me, so perhaps I could also accept it in Rust
    This blog compares in detail Java and Rust generics:

    It seems to answer your questions.


    • Originally posted by xfcemint View Post
      Ok, now I have a question (in order to avoid reading a big pile of documentation, lazy me).
      It'd honestly be easier and quicker to skim through the Rust Book to find what you want to know, or asking questions on the Rust subreddit or Rust User's Forum.

      - still the question remains: polymorphic caches or vtables? If there are polymorphic caches, can it do multiple dispatch?
      Compile-time polymorphism when generic types are used, and dynamic dispatch when trait objects are used​.

      Why are types in a generic function erased? Is this something on a to-do list, or some strange kind of a design decision? I would certainly prefer that no type erasures are part of the language.
      I think you need to first define what your definition of type erasure is, because the behavior of Rust is the same as other compiled languages. Except for trait objects, generics are used for compile-time code generation. Any time you call a generic function, the compiler automatically generates a unique function or type based on the types you supplied to it. Type metadata generally isn't needed by a compiled application. If you never write code that requires runtime type checking, then there's zero point in requiring type metadata to be attached to every value.

      It's possible to create a variable that can be any type with runtime type-checking by passing it as a `&dyn Any` or `Box<dyn Any>`, but that's something that's very rarely if ever used by anyone in the real world outside of playground demos. It's more typical to see variables passed around as trait objects (`&dyn MyTrait`, `Box<dyn MyTrait>`), where the types are restricted to types implementing the given trait. Some people do like to do runtime type checking for errors though, since the error trait can retrieve the cause of an error as a `&dyn std::error::Error`, which you can upcast to a specific type implementing that implemented trait.

      It got them faster than I thought possible.
      These features were all implemented before Rust 1.0 released about 7 years ago. In recent times, async capabilities were implemented and Rust is now focused on improving the async story. It also just gained GATs (generic-associated types), which brings it closer to HKTs and enables even more advanced and ergonomic forms of async.

      One such demanded feature is async methods in traits, which in practice can be achieved with a non-async method returning a `Box<dyn Future>`, but to be truly zero-cost it needed support for GATs and specializations. With GATs down, work on specialization can proceed to enable native syntax for async methods to work with zero cost.
      Last edited by mmstick; 29 November 2022, 11:00 PM.


      • Originally posted by xfcemint View Post
        Both polymorphic caches ad vtables are "dynamic dispatch", so which one?
        Polymorphic caches = Haskell ; vtables = C++.
        Dynamic dispatch is most commonly achieved with an enum, which some academics call ADTs (algebraic data types). They're deconstructed with pattern matching and many people familiar with Haskell will feel right at home using these. No vtable or runtime type annotations needed.

        It's rare to see it, but passing values as a `dyn Trait` — also known as a dynamic trait object, and usually constructed as `Box<dyn Trait>` — will have the compiler generate a vtable alongside the data that enables the functionality of the given trait. A value being passed in this manner could theoretically have multiple vtables if it's being passed into interfaces with different `dyn Trait` types, with one vtable per trait.

        In most cases, static dispatch is the most common form that generics takes. No vtables are needed with that. Dynamic dispatch with trait objects is typically used to avoid static dispatch with functions, and to avoid polluting the type signature of a type containing a generic field.
        Last edited by mmstick; 29 November 2022, 11:38 PM.


        • Originally posted by xfcemint View Post
          Oh, and I have the final question: Is there an IDE for Rust that features code completion? Not the idiotic "wild guess" kind, but the full-analysis kind, where I can pick an identifier name from a tree of pop-up boxes. Also, debugging with a call stack window, variables window and pretty-printing are important to me. Preferably, it should be free and open-source.
          Today, the standardized method of code completion in Rust is through Rust Analyzer, which is an official project maintained by the rust-lang team. It is an implementation of the Language Server Protocol. Any editor that supports LSP has a Rust plugin, and VS Code is probably the best example of that. The LSP can show inline type hints, highlight the precise characters and lines that are emitting warnings and errors, give code suggestions, documentation tooltips, goto, and it does give the drop down box of options as you type, and when you press the Ctrl + . shortcut.

          IntelliJ decided to implement their own Rust plugin from scratch rather than relying on official LSP implementation.