Live data from Hacker News

The Rust borrow checker from a different perspective

blog.systems.ethz.ch

31–40 of 51 posts

Re: The Rust borrow checker from a different perspective

#31
post #14
post #10

From that writeup, it seems like one is forced to program Rust in an object oriented manner. Is it possible to program it in a functional manner like Lisp, or a procedural manner like BASIC or assembler?

In my experience, it’s not much more OO than Haskell. Even in many functional languages, you typically want some OO — you’ll want some core type that you export opaquely, and then you have functions doing logical operations on that. I think two of the biggest differences are: - Because the type and memory systems make it possible to skip heap allocation if you’re careful, it’s “idiomatic” to prefer avoiding technique…

"Even in many functional languages, you typically want some OO"

No, never, because it makes the state machine incredibly hard to follow and an absolute nightmare to debug. From experience.

Re: The Rust borrow checker from a different perspective

#32

Earlier quoted context omitted.

> That's only partially true though. Rust does support interface inheritance and polymorphism in its trait system. It supports no more than Haskell's typeclasses (rather less in fact), are typeclasses an object system? > And enums are a closed form of sub-typing. Rust enums are pretty standard sum types, a staple of statically typed functional languages. > RAII is also idiomatic and I'd argue that many would class th…

> are typeclasses an object system No, did someone say they were? > Rust enums are pretty standard sum types, a staple of statically typed functional languages Indeed I'm not entirely sure what your point is. Functional and OO aren't mutually exclusive.

"Functional and OO aren't mutually exclusive."

They must by definition be. I disagree vehemently with your statement. If you were correct, then there would be absolutely no point to programming "functionally", it would be absurd. Might as well go back to programming in Java or C++, which is utterly counterproductive.

Re: The Rust borrow checker from a different perspective

#33
post #15
post #10

From that writeup, it seems like one is forced to program Rust in an object oriented manner. Is it possible to program it in a functional manner like Lisp, or a procedural manner like BASIC or assembler?

I wouldn't say that object oriented is completely opposed to functional, though.

I would. That's the whole point: in object-oriented programming, everything revolves around the state machine, whereas in functional programming, every function is idempotent and the state machine irrelevant. Lisp is a good example of that.

Re: The Rust borrow checker from a different perspective

#34
post #7

Earlier quoted context omitted.

The short answer, devoid of some interesting nuance, is that C++’s template system is similar to an untyped functional programming language, so the errors you get are the compiler’s attempt to make sense of the large tree of nonsense it couldn’t reduce. C++ also suffers from years of backwards-compatibility twister creating abundant cases of ambiguity if you do something wrong. The compiler will do it’s best, but if…

> Rust is far simpler in that regard, so there are fewer instances where your code might accidentally make sense to the compiler if you have an error. I say this from a place of love for Rust, but the first time you run into a massive generic type tree error thats root cause is a type parameter three levels deep not implementing Send (or some other trait) it takes your breath away. There are some great jokes about th…

Similar stuff happens on Haskell too. I guess that since the type system is an unityped logic programming language, it is an even worse place than C++ templates. It is a smaller problem on practice only because the type declarations are much shorter programs than C++ templates.

Re: The Rust borrow checker from a different perspective

#35

Earlier quoted context omitted.

> That's only partially true though. Rust does support interface inheritance and polymorphism in its trait system. It supports no more than Haskell's typeclasses (rather less in fact), are typeclasses an object system? > And enums are a closed form of sub-typing. Rust enums are pretty standard sum types, a staple of statically typed functional languages. > RAII is also idiomatic and I'd argue that many would class th…

> are typeclasses an object system No, did someone say they were? > Rust enums are pretty standard sum types, a staple of statically typed functional languages Indeed I'm not entirely sure what your point is. Functional and OO aren't mutually exclusive.

> No, did someone say they were?

You're implying that Rust's traits "partially" make for an object system. Given Rust's trait are essentially a restricted form of Haskell's typeclass, these would by your assertion "partially"+ make for an object system as well.

Re: The Rust borrow checker from a different perspective

#36
post #32

Earlier quoted context omitted.

> are typeclasses an object system No, did someone say they were? > Rust enums are pretty standard sum types, a staple of statically typed functional languages Indeed I'm not entirely sure what your point is. Functional and OO aren't mutually exclusive.

"Functional and OO aren't mutually exclusive." They must by definition be. I disagree vehemently with your statement. If you were correct, then there would be absolutely no point to programming "functionally", it would be absurd. Might as well go back to programming in Java or C++, which is utterly counterproductive.

"functional" is a description of algorithm (or program), but not language. Languages usually have ways to program in different styles.

Re: The Rust borrow checker from a different perspective

#37
post #33
post #15

Earlier quoted context omitted.

I wouldn't say that object oriented is completely opposed to functional, though.

I would. That's the whole point: in object-oriented programming, everything revolves around the state machine, whereas in functional programming, every function is idempotent and the state machine irrelevant. Lisp is a good example of that.

Are you giving Lisp as an example of functional or object-oriented programming?

I mean, Common Lisp has had CLOS since at least 1984.

Re: The Rust borrow checker from a different perspective

#38
post #29

That's a nice way of introducing type state programming in an affine programming language! In general though, type state programming would be even nicer in a linear language. For example, in the http server I could start writing a response without ever writing a body. Rust would happily accept this code, because Rust is always allowed to throw away resources. An affine language controls the duplication of resources,…

[deleted]

Re: The Rust borrow checker from a different perspective

#39
post #30
post #12

Earlier quoted context omitted.

Just to be clear, rust is not object oriented. You do not use inheritance nor do you have objects. There was a recent post comparing rust to haskell https://www.fpcomplete.com/blog/2018/10/is-rust-functional . And tldr is yes it lends itself to a functional style...

lorry.pickup(&rustfest_envelope); lorry.done(); looks like methods on an object ("lorry") to me. Is it something else?

Yes. Rust does not have objects. Method call syntax isn’t inherent to objects.

Re: The Rust borrow checker from a different perspective

#40
post #22
post #14

Earlier quoted context omitted.

In my experience, it’s not much more OO than Haskell. Even in many functional languages, you typically want some OO — you’ll want some core type that you export opaquely, and then you have functions doing logical operations on that. I think two of the biggest differences are: - Because the type and memory systems make it possible to skip heap allocation if you’re careful, it’s “idiomatic” to prefer avoiding technique…

Regarding closures, note that Rust closures don't allocate on the heap unless you explicitly use a Box to put them on the heap. Long-lived closures aren't a problem, because closures by default borrow the variables they close over (and like all borrowed references, these cannot extend the overall lifetime of the borrowed data); alternatively they may take ownership of their closed-over variables, but in that case the…

A closure taking ownership of the closed-over variables doesn't actually imply that it is FnOnce (only callable once). You can perfectly well have a Fn or FnMut closure that owns its captures, as long as you don't try to do any moves inside the closure. If you need to do a move in an FnMut closure, you can also wrap the captured variable in an Option, and use .take()
Post reply on HN