• 0 Posts
  • 24 Comments
Joined 1 year ago
cake
Cake day: June 15th, 2023

help-circle


  • It really depends on what you are doing with your system…

    On my main PC I want the full Linux Desktop experience, including some Gnome tools that require webkit - and since I am running Gentoo, installing/updating webkit takes a lot of RAM - I would recommend 32 GiB at least.

    My laptop on the other hand is an MNT Reform, powered by a Banana Pi CM4 with merely 4 GiB of memory. There I am putting in some effort to keep the system lightweight, and that seems to work well for me up to now. As long as I can avoid installing webkit or compiling the Rust compiler from source, I am perfectly happy with 4 GiB. So happy actually, that I currently don’t feel the need to upgrade the Reform to the newly released RK3588 processor module, despite it being a lot faster and it having 32 GiB of memory.

    Oh, and last, but not least, my work PC… I’m doing Unreal game development at work, and there the 64 GiB main memory and 8 GiB VRAM I have are the absolute bare minimum. If it were an option, I would prefer to have 128 GiB of RAM, and 16 GiB of VRAM, to prevent swapping and to prevent spilling of VRAM into main memory…




  • Visual Studio Code with rust-analyzer has all the features I would expect from an IDE. I mean, rust-analyzer works together with cargo, so refactoring over file boundaries is not an issue. Visual Studio Code has built-in support for debugging and source control…

    That said, I am currently trying to change my workflow to use vim instead of Visual Studio Code, due to my laptop’s small screen size. Rust-analyzer works great in vim too, but I still need to tweak a few things, like how warnings from cargo check are being displayed…


  • I’m mostly using Rust for a spare time Visual Novel Engine (and Visual Novel) project.

    I picked Rust, because I wanted to do something productive with my higher-free-macro crate (which is a tech-demo, but hey, if I have written it, I can just as well use it for something). If you want to get an idea how scripting the VNs in that engine will work, check out the “text adventure” example in higher-free-macro. However, Rust is definitely not an ideal choice for this project. Since performance usually isn’t a concern for visual novels, a higher-level, pure functional language like Haskell or Lean4 would probably have been a better option.

    Apart from that I’m using it for many smaller things. For instance I’ve written a small tool for my status bar, swaystatus. (I was not aware that i3status-rust exists when I started working on it, and now I am already committed.) Here I chose Rust mainly because I wanted to learn about Foreign Function Interface in Rust. While I didn’t upload the sources to github until recently, I mostly had been working on this tool several years ago, when I still was a Rust newbie. However, I got back to this project some weeks ago, when I realized that I would like to have an ALSA volume display, which is now in a WIP state on a separte branch.

    I’m also using Rust for some out-of-tree prototypes at work. In this case the main reason for choosing Rust is development speed. I’m using Iced.rs to build those prototype GUIs, and Iced is an amazing toolkit. Making a prototype with it is shockingly fast. If I were to do something similar with basically any other GUI toolkit, it would take me significantly longer.

    And last, but not least: I’ve published a free app for SailfishOS which is compatible with passwordmaker.org: Passfish, and its underlying library, passwordmaker-rs. Here I chose Rust, because it’s way less error prone than C++ (and let’s better not talk about QML JavaScript). Also, I wanted to show that using Rust for SailfishOS app development is viable, and that it’s actually a quite pleasant experience. (If you want to try passfish, builds are available via the official SailfishOS store, or on OpenRepos).



  • I wouldn’t call Monads a “language feature” of Rust.

    There are some types in the standard library that have Monad properties (Option, Result, Vec,…), but there is no Monad trait that would allow to be generic over them.

    There have been attempts to introduce such a trait, the most well known probably being the higher crate. However, even with that crate, it’s not easy to work with Monads.

    For instance, in the stable tool-chain, it’s currently (to my knowledge) not possible to express a Free Monad without using macros. If you care for the details, I’ve written a blog post about my Adventures with Free Monads and higher. With the Nightly toolchain it is possible to write a generic Free Monad, by the way, thanks to non-lifetime-binders.

    Other Monads, like State, Reader and Writer, are also challenging to implement in Rust. I did get them to work, however I failed to implement Applicative for them, so, while they are mathematically Monads, they do not have higher’s Monad trait. Here a possible future improvement of non-lifetime-binders could help. Again, a blog post: Writer and State Monad in Rust, based on higher.

    Oh, and last, but not least, do-notation in Rust is a bit inconvenient, because of lifetime rules and lambda captures. For instance, using non-copy types is messy. I’ve added explicit clone support to higher, but that’s a crutch, and overly verbose.


  • Technically not free, but rather pay what you want. You can still grab the original version from the official website.

    Iirc the Plus version was originally made because of consoles. The original game was very PC specific, as you needed to

    Spoiler

    touch the files in the game’s install folder

    to be able to complete it, and to find some otherwise hidden content. That’s of course not possible on consoles…

    I haven’t played the Plus version, because I think that having an in-game

    Spoiler

    computer desktop

    is a massive spoiler. Also, I think it changes the perspective a lot, as there’s an intermediate layer in-between that you don’t have if you

    Spoiler

    directly interact with the game, and have the game running on your own PC instead of a simulated interface.

    But, as said, I haven’t played it, so it might not actually feel as different to the original game than I fear it does.




  • soulsource@discuss.tchncs.detoRust@programming.devWho's working on a "smaller Rust"?
    link
    fedilink
    English
    arrow-up
    5
    arrow-down
    3
    ·
    edit-2
    6 months ago

    Haskell.

    I’m not joking. If you want something that’s very similar to Rust, but doesn’t have the restriction of being a systems language, then Haskell might be the right thing for you. Unlike Rust, Haskell is Pure Functional though, so it forces you to have an even cleaner architecture.

    If Pure Functional isn’t your beer, then you could also check out the language that inspired Rust: ML. If I remember correctly, Rust was started as “something similar to ML, but suitable for systems programming”. So, it only feels natural to take an ML dialect if you want “something similar to Rust, but without the restriction of it being suitable for systems programming”.

    A popular ML dialect would for instance be F#, which is built on top of the .Net runtime and is therefore compatible with C# and the likes. On the other hand, in order to make it compatible with C# and the likes, there are some weird compromises in F#…

    Or, if you (like me) dislike the idea of having a Garbage Collector, you could go for Lean4. That’s what I’m learning currently, and it feels a bit like a bastard child of Haskell and ML.


  • We are in a better situation regarding the addition of new languages. Most of our devs (don’t know the exact count, 40-50 I guess) are dissatisfied with C++ in one way or another. Our company started out with Unity (which uses .Net), so most of our senior devs have experience with other languages too, and those who don’t are generally young people who haven’t had time to get stubborn yet 😜.

    Our technical director pushes towards functional programming pretty strongly, and he gave most of us the opportunity to participate in a course by FP Complete, which was a bit about Haskell, but mostly about Rust. So, most of our coders have at least seen Rust. Some liked it enough to do spare time projects in it, and as far as I can tell there is no strong dislike towards the language from anyone in our team.

    However, there is no consensus yet amongst seniors which language besides C++ we should introduce. Our tech director leans towards Rust for business reasons (-> the argument is that many devs like Rust, so finding Rust devs should be easy). Some, though they dislike C++, would rather keep it exclusively, as they doubt the benefits of other languages would outweigh the overhead (training, writing FFI bindings). Then there are those (including me) who would go directly for a pure functional language…

    And last, but not least, there is the biggest reason why we haven’t introduced any languages besides C++ yet: Time. We would need time to experiment with integrating languages into our tooling, and we simply are too busy at the moment to do that…


  • The “it’s hard” claim is also a bit of a misconception imho. Rust for sure has a high entry barrier, but it isn’t particularly difficult, at least in comparison with C++, which I’d consider its biggest competitor. While it’s easy to start working with C++, it’s a horribly complex language with hard to use features, lots of weird edge cases, and tons of missing pieces, that one has little chance of ever learning properly, because it’s just so much to keep in mind at all times… Oh, and don’t get me started on how error prone memory management is without a Borrow Checker…

    Sorry for the rant, back on topic: I agree that it’s not the right tool for many domains. That’s what I was thinking about when I wrote that people might misunderstand what niche it tries to fill. If one needs a low level language that is very explicit about performance costs, and offers memory safety and (some) abstraction at zero runtime cost, then Rust is definitely worth a look. If performance is not a key concern, then higher level languages might be a better choice, because one can build things faster, and focus more on the problem at hand instead of low-level details.

    We are at work in a similar situation, as we would like to add another programming language besides C++ to our projects, and Rust is currently the top candidate. However, one of our goals is to use abstractions that are common in functional programming, and that’s where I think Rust is a suboptimal choice. I’ve been playing around with such abstractions in Rust recently (I’ve written blog posts about Free Monads and Reader/State Monads in Rust), and my conclusion is that Rust isn’t the right tool if one wants to use those. (Or, rather, those abstractions are not suited for the domain of systems programming.)

    We are using Unreal Engine, so C++ is the obvious choice for performance critical code. Rust would then fill the same niche, and while it obviously would be much more convenient to use than C++, we would still need to train people, and set up FFI bindings. If we, however, are already willing to do that, we could also go all the way and introduce a higher level pure functional language. That way we would actually get a tool that covers a different domain and is suitable for abstractions coming from functional programming. We could then choose, based on a system’s requirements, if we need to focus on performance (-> C++), or if we can trade a bit of performance for much easier to write/maintain code (-> whatever high level functional language we pick).

    That’s why, as it stands now, I also won’t push towards the adoption of Rust at work.


  • Controversial opinion: There are only 2 kinds of people that think Rust will not become a widely used language:

    • Those who don’t bother to learn it, and only argue about it without any hands-on experience, and
    • those who don’t understand which niche Rust tries to fill.

    For me it was funny, btw. I started out as basically a Rust fanboy, back when the “First Edition of The Rust Book” was still just called “The Book”…

    Then I learned a bit of Haskell, and was immediately disappointed that Rust doesn’t offer the same convenience when it comes to working with Traits (cough Higher Kinded Types cough). So, while I never considered myself part of the first group, I definitely was part of the second for some time.

    However, the more I’ve been trying to abuse Rust for stuff that would be better done in a higher level language (like Haskell), the better I understood why Rust doesn’t offer those abstractions: They often can’t be zero-cost, and using them in a language that tries to be very explicit about performance costs becomes very verbose… In other words, I learned the hard way what “systems programming” means in the case of Rust, and which languages it competes with, and which it doesn’t.


  • I didn’t look beyond the main parts of the HTTP moduel, but what I’ve noticed basically immediately was that your pub fn start_server(address: &str, request_handler: fn(Request) -> Response) -> io::Result<()> uses a function pointer parameter.

    This is overly restrictive. fn a()->b only accepts fns, and closures that do not capture their environment (see the book’s chapter on closures). In order to accept closures that capture their environment, you could make that function generic: pub fn start_server(address: &str, request_handler: F) -> io::Result<()> where F : Fn(Request)->Response + Clone +'static.

    • The Clone requirement is necessary, because you need to pass a copy of the handler to each spawned thread.
    • The 'static lifetime is needed because you can’t guarantee that the thread doesn’t outlive the call to start_server.

    Now, this can be improved further, because Rust offers a tool to guarantee that all threads are joined before run_server returns: Scoped Threads.

    • Scoped Threads make the 'static requirement unnecessary, because the function that contains them outlives them by definition.
    • In addition, the Clone requirement is not needed either, because due to the limited lifetimes, you can take request_handler by reference, and all references are Copy (which is a subtrait of Clone).

    With scoped threads, a version of your function that could be generic over the request_handler could look something like this (I haven’t tried to compile this, it might be utterly wrong):

    pub fn start_server(address: &str, request_handler: &F) -> io::Result&<()> where F : Fn(Request) -> Response {
        let listener = TcpListener::bind(address)?;
        std::thread::scope(move |s| -> io::Result<()>{
            for stream in listener.incoming() {
                let stream = stream?; // I think ? works here too
                s.spawn(move || {
                    handle_connection(stream, &request_handler);
                });
            };
            Ok(())
        })
    }
    

    Edit: Sorry for the messed up characters. & should of course just be the ampersand character, and < should just be the less-than character.



  • Before you get overly excited, we plan to introduce it later this year. As in game-dev “plan”, as in “it might be cut or delayed” 😜. What is holding us back is that we need time to get a Rust toolchain set up for all our target platforms, which have certain requirements that the toolchain needs to meet, and time is always a tight resource in game dev.

    That said: Our technical director is very adamant at pushing us towards a more functional programming style (his website explains why). If we could, we would go pure functional right now, but it’s really hard to find people who have experience with fully functional languages, and therefore we want to have the next-best thing, which is Rust. (Or F# for Unity projects. We don’t have any Unity projects right now, but we already have used F# in Rescue HQ, for instance.)

    And finally, to answer your questions: I work at stillalive studios. Here is a list of our open positions: https://stillalive.games/careers/ Also I can say from personal experience, that the “speculative application” paragraph is definitely true.