4 ms·
Don't mutable and immutable references with lifetimes count? Sure, one could argue whether the borrow checker is really part of the type system, but it's a comp
by mpartel 9y ago
Don't mutable and immutable references with lifetimes count? Sure, one could argue whether the borrow checker is really part of the type system, but it's a compile-time check either way.
Yes, in the standard library, an immutable object can hide mutable state in e.g. a 'Mutex', and effects to the external system aren't wired through anything like monads or unique objects.
I see those as compromises Rust makes in the name of pragmatism and being a system'ey language. I don't necessarily like all of them, but I find the general uniqueness typing based approach interesting.
See articles comparing Clean and Haskell for an interesting historical perspective, including how both approaches could be used to model side-effects in a purely functional language. Haskell "won", possibly because it was seen as more generic and composable. I always felt Clean's approach had merit too, so I was really glad to see Rust bring the idea, or a closely related idea, to prominence.
- xfer 9y agoRight, but you are addressing only part of the story to side-effects. IO is another story, which rust doesn't address.
- mpartel 9y agoThe standard library doesn't, and most crates don't, but I'm pretty sure nothing prevents you from writing libraries in a style where all IO requires mutable access to some explicit unique "World" object, similar to Clean. Passing a unique world object around is effectively the same as composing with the IO monad, and borrowing 'f(&mut world)' is basically equivalent to 'let world = f(world)'. Maybe someone will one day write a standard library in that style.
- xfer 9y agoIt is not going to be convenient because rust doesn't have higher kinds. I see people making this argument in other language contexts e.g. Ocaml; but they have no typeclasses, which make writing monadic style code extremely inconvenient.