1. 24
  1.  

  2. 3

    I’m curious to see why Rust is considering Monads. Is the Rust Community going towards FP? Data Abstraction that FP has does seem like a good fit for rust but on a conceptional basis why would you need a Monad in rust when Rust is already imperative and can produce side effects?

    1. 7

      It doesn’t look like “Rust” is considering this. More like a few people who code in Rust wanting to expand it. Official response:

      “Please note that these are musings about possible language extensions that would let us express monads; this is not even at the stage of a proposal yet, and we haven’t all agreed that enabling this kind of code is actually useful. However, community sentiment is all over the map… reddit thread on this post, you can see a number of different opinions expressed there.

      I personally want to see examples of real Rust code that has a problem that this solves. I get monads, I like monads in Haskell, but I’m unconvinced that the additional complexity is worth it in Rust. “ (Steve Klabnik)

      1. 4

        It doesn’t look like “Rust” is considering this.

        Exactly, it’s a personal musing of a member of the lang team. We want to have that, but it is definitely a personal mental exercise.

      2. 4

        If it remains a PLT musing, that’s fine, but I would be unhappy if this came to be implemented in Rust. It would add complexity to a language that’s already pushing its complexity budget. I don’t think that Rust needs to appeal to everyone: it’s okay if Haskell programmers don’t find their favorite abstractions (functors, monads, applicatives) in Rust, just as it’s okay if Java programmers don’t find theirs (classes, inheritance, etc.).

        1. 1

          Not to mention we can use different tools for the jobs they’re good at. At least one person here is mixing Haskell and Rust. Some others were doing that with Erlang. So, Rust steps in with its own style to handle anything that would force such people to drop down to C or jump through crazy hoops. They keep writing everything else in the preferred language.

          1. -1

            Maybe it would make sense to remove all that silly complexity and cut down on the constant feature additions, instead of blaming looming complexity on support for some of the most fundamental abstractions?

            Drop mandatory semicolons, replace generics’ <> with [], turn special indexing syntax into normal function calls, replace :: with ..

            There, removed loads of complexity that people experience daily.

            1. 5

              None of these even comes close to being a daily complexity for me: they’re just lexical syntactic concerns, not very high on my list of things that Rust needs to be wary of.

              1. 1

                I could probably go on for hours about the semantics, but you have to start somewhere.

                If even the basic syntax is needlessly complicated and you are fine with it, then it’s not a surprise that Rust’s complexity grows with every release. I think Rust’s development is too often focused on asking whether they can instead of asking whether they should.

          1. 1

            “a language with the lambda syntax of C++ and the performance predictability of Haskell”

            Intercal has some competition coming.

          2. -5

            We need an actual replacement for C and the Rust team is bickering about monads.

            Rust seems like a playtoy for CT students. A toy won’t be used by people for serious projects in the long run.

            Adding a single new way to express types means that everyone needs to learn this new feature. Even if some sane project forbid its use, others won’t and all practictioners will need to be familiar with the entirety of the language to be able to efficiently and safely use the language.

            When will we have C with a borrow-checker? A new PL language is certainly nice and a good stroke to the ego of a few, but it won’t solve current pressing issues.

            1. 8

              “A toy won’t be used by people for serious projects in the long run.”

              It’s used in serious projects by businesses right now. Example. There’s also two OS’s, one for desktops and one for microcontrollers. It’s already more than a toy. I think there’s a lot of people that like C’s style who won’t adopt something as different as Rust, though. Zig is promising as something they might like.

              “When will we have C with a borrow-checker? “

              I’ve argued for that myself. The best of the safer C’s that might be given Rust’s borrow-checker in version 2 were Clay and Cyclone. Whatever is built needs to stay close to C’s actual style to get more people interested in it. C was not designed for verification, though. So, this means all the difficulties of analyzing its safety go up as one gets close to its current design and implementations. Maybe someone will figure out a simpler, safer, and still C-enough design. If not, people won’t move unless they have to.

              Hence, why I favor regulations that force memory safety into apps. Then, they’ll use Rust, D, design a better C… anything that outweighs the fines or legal damages from their avoidable vulnerabilities.

              1. 0

                Is there a language that expresses lifetimes as types that can be shared by objects?

                There would be the two default lifetimes ‘static’ and ‘’ (on the stack). Then one would have to describe the equivalent of the Send and Sync trait for any other lifetimes, which would describe how the memory will be allocated, how it will be read, written and then freed.

                This means that you’d have lifetimes describing exactly how a memory block will work, and a borrow-checker would be able to verify that objects used in an interface would respect the expected lifetime.

                The Rust notation is clunky and limiting. Lifetimes seems like an afterthought, something that had to be slapped on the type system to make the borrow-checker happy. But it should be central and explicit.

                I’m not asking for a C-like syntax. I’m asking for C-like simplicity and clarity. Structs and memory maps should not be inheritable, no generics. Lifetimes could however be scoped (when an object embeds another).

                Then there should be the sane practices like const by default, NULL sumtype, utf-8 string slices (and accompanying library) (Rust is doing that perfectly).

                1. 2

                  “The Rust notation is clunky and limiting. Lifetimes seems like an afterthought, something that had to be slapped on the type system to make the borrow-checker happy. But it should be central and explicit.”

                  I can’t answer you on that. I do like putting things in perspective. Your wording makes it seem like there’s a ton of languages doing borrow checkers with Rust having a shitty one. There’s only two that I know of with Rust having made it (Clay didn’t). All the other languages either don’t have safety or have runtime cost.

                  Also, the property is none of these temporal errors on all inputs. That’s similar to formal verification. Before Rust, the way you do that for a systems program (esp C) was separation logic. Microsoft’s tool, VCC, was better than most. Their proof specialists were cranking out two lines of code a day on average. Rust has people learning data-orientied design, their language constructs, and certain amount of time to make it click to get same result. That’s a major improvement.

                  Whatever you’re advocating needs to do what selaration logic does for imperative, low-level code with at least the usability and ergonomics of Rust. There’s your goal post. Post it when you find or design it. :)

              2. 5

                We need an actual replacement for C and the Rust team is bickering about monads.

                I don’t think it’s the Rust team, nor bickering; more like the musing of a fan of Haskell who sees Rust as his ticket to using FP in production. If that stays at the stage of musing or if it becomes the foundational idea for a new programming language (i.e., not Rust), then all the success to the author.

                I came to Rust a few years ago from OCaml. At first, I tried to use Rust in an OCaml style, and I was thoroughly put in my place by the compiler. The functional style goes against the grain in Rust—many methods work by mutation (e.g., concatenating two vectors) rather than by returning new values as in functional languages; many of the cool techniques of FP (e.g., persistent data structures) are either impossible or way too inconvenient for Rust. I’ve also struggled trying to use some methods (e.g., HashSet::union()) in a functional style; the union method returns an iterator rather than an actual object and taking the union of three objects efficiently turned out to be quite difficult; I ended up using mutation and it was easy and simple:

                let mut a = ...;
                let b = ...;
                let c = ...;
                for elem in b { a.insert(elem); }
                for elem in c { a.insert(elem); }
                

                After being thwarted enough times, I began using Rust like Rust wants to be used—like a procedural language. There’s no point in trying to force the language into a style that it’s not suited for: the language gets more complex (and Rust certainly doesn’t need anymore of that) and the costs in the future will be high for little (I think) benefit.

                Edit: Here’s the code for doing the union of three sets in functional and procedural styles: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=c1f3b54ef83a4e017b6865db2be6ffac