8 ms·
I'm working with Rust 2 months. In my opinion, pluses: + Compiler with very helpful error messages; + Cargo is the best package manager in the universe; + Re
by EugeneOZ 11y ago
I'm working with Rust 2 months. In my opinion, pluses:
+ Compiler with very helpful error messages;
+ Cargo is the best package manager in the universe;
+ Result<> is the most correct way to return results from function, I dreamed about it;
+ Community of smart and friendly people.
Minuses:
- Functions are not first class citizens - you can't return function as result;
- Violation of "explicit over implicit" rule in methods declarations: argument self/&self is implicitly omitted in call, but exist in signature. Because of this, for example, you can't use method of class as request handler in Iron, you need closure wrapper with same order and count of arguments. Pure ugliness;
- Often you need just add lifetime definition to satisfy compiler, without doing anything with this lifetime anywhere else in code;
- Extremely verbose syntax;
- Rust has exceptions (panic), and you can't catch them. And with promised panic::recover you'll have limitations of supported structures;
- Errors handling encourages copy-pasting;
- Syntax is not intuitive, especially when traits and lifetimes comes into declaration - in such cases you can look at own code and think "I hope at least compiler can read it";
- Nested structures is pain;
- Lack of optional and named arguments, lack of predefined values in structures;
- Too few modules for web. Just 1 module for MySQL (thanks to it's author - actively maintained);
- Usage of safe code can lead to out-of-bounds errors, with thread panic (hello to vec macros).
And I still think it's best language we have:) Biggest advantage - most of errors can be found on compilation step. But price is all of these minuses.
- adrusi 11y agoViolation of "explicit over implicit" rule in methods declarations: argument self/&self is implicitly omitted in call, but exist in signature. Because of this, for example, you can't use method of class as request handler in Iron, you need closure wrapper with same order and count of arguments. Pure ugliness; Maybe that's ugly, but it's explicit. The method is statically compiled into the program to take the receiver as an argument. What you want to do is specify the receiver argument on the caller cide and the remaining arguments on the callee side, which is impossible to do. The closest you can get is to create a closure on the caller side and pass that to the callee. Languages that avoid this, like say, python, are just implicitly creating that closure. Creating a closure implicitly goes against the design goals of rust. At least rust doesn't have javascript's abominable semantics.
- kzrdude 11y agoYou can pass methods as functions or closures by Type::method. The first argument will be the self argument. I don't see much of an alternative to panic on bounds checked indexing error, short of not providing indexing at all or developing a system of proven indices that would be extremely unfriendly to newcomers, see this project: https://github.com/bluss/indexing https://github.com/bluss/indexing
- EugeneOZ 11y agoNo, you can't do it when you need &self.
- kzrdude 11y agoYou have me guessing you want a bound method where self is implicitly supplied. Sure, there's no sugar for that.
- dbaupp 11y agoYou can, e.g. struct Foo; impl Foo { fn bar(&self) {} } fn main() { let x = Foo; Foo::bar(&x); } What you may be encountering is you can't pass a `Foo` when a `&Foo` is expected (why I needed to write &x), because the types differ. Calls with method syntax don't see this because they automatically borrow the receiver if necessary, but explicit function calls do not do this sort of borrowing and so the types need to line up right.
- masklinn 11y ago> I don't see much of an alternative to panic on bounds checked indexing error Returning an Option. That's what Elm does: head : List a -> Maybe a get : Int -> Array a -> Maybe a It tends to drive people towards not indexing collection (which is often good).
- killercup 11y agoRust's std::slice has a `get` method that does exactly that: http://doc.rust-lang.org/std/primitive.slice.html#method.get http://doc.rust-lang.org/std/primitive.slice.html#method.get
- heinrich5991 11y agoThe "return function as result" is being worked on: https://github.com/rust-lang/rfcs/pull/1305 https://github.com/rust-lang/rfcs/pull/1305
- masklinn 11y agoTechnically it already works, but you have to either return an actual function, or return a boxed closure (because trait object)
- masklinn 11y ago> - Functions are not first class citizens - you can't return function as result; Of course you can: http://is.gd/YASF8T http://is.gd/YASF8T One issue is that closures don't really have their own types, so to return closures you need to use trait objects, which means dynamically-sized types, which means you have to box them - Rust book on the subject: https://doc.rust-lang.org/book/closures.html#returning-closures https://doc.rust-lang.org/book/closures.html#returning-closu... - Example of returning a boxed closure: http://is.gd/pJIqiu http://is.gd/pJIqiu > Violation of "explicit over implicit" rule in methods declarations: argument self/&self is implicitly omitted in call, but exist in signature. That's a debatable assertion, in a method call, the self/&self is the subject, the part before the dot. > Because of this, for example, you can't use method of class as request handler in Iron, you need closure wrapper with same order and count of arguments. By "class" what do you mean? Because AFAIK it works on struct methods http://is.gd/xu6HRc http://is.gd/xu6HRc > Rust has exceptions (panic), and you can't catch them That's because Rust doesn't have exceptions, it has panics, they're not a general-purpose error-reporting or control-flow mechanism. > lack of predefined values in structures http://doc.rust-lang.org/std/default/trait.Default.html http://doc.rust-lang.org/std/default/trait.Default.html > Usage of safe code can lead to out-of-bounds errors, with thread panic (hello to vec macros). Safe rust doesn't mean no panics. `panic!` is safe rust.
- EugeneOZ 11y agoprintln() is not Iron request handler, you gave wrong example. Signature matters. I don't see how you can declare field if structure to have default value 65535, even with Default trait. I posted opinion not to argue and really frustrating to see downvotes for opinion. Make discussion more constructive.
- masklinn 11y ago> println() is not Iron request handler, you gave wrong example. Signature matters. println is not relevant here it only shows the result of the call, the point is that you can use a method as a function, I expect the issue is elsewhere (but not having used Iron, I wouldn't know where). > I don't see how you can declare field if structure to have default value 65535, even with Default trait. Implement Default then call it when instantiating struct: http://is.gd/2YSoKd http://is.gd/2YSoKd > I posted opinion not to argue and really frustrating to see downvotes for opinion. Make discussion more constructive. Er… I didn't downvote you? I just replied to some of your objections which I assume is what you expected?
- lmm 11y agoHave you compared with a modern typed functional language e.g. OCaml, F#, Scala, Haskell? I'm pleased that Rust is making a lot of these functional things more mainstream, but for normal application code where GC is acceptable Rust adds a lot of unnecessary overhead. (Personally I use Scala, but using Maven for dependency management rather than SBT. It doesn't tick all your boxes (in particular I'm thinking of one specific member of the "community") but it's close, and deals with a lot of your minuses)
- deleted 11y ago[deleted]
- steveklabnik 11y agoInteger overflow is different than out of bounds access, which still panics in release.
- valarauca1 11y agoI stand corrected thanks
- EugeneOZ 11y agoLooks like my information about returning functions is outdated (although issue in tracker isn't closed). Thanks to all who pointed it. Now I love Rust even more and sure with time all other minuses will be polished out :)
- Manishearth 11y agoFair points, though many of these aren't as bad as they seem. > Violation of "explicit over implicit" rule in methods declarations: argument self/&self is implicitly omitted in call, but exist in signature. Because of this, for example, you can't use method of class as request handler in Iron, you need closure wrapper with same order and count of arguments. Pure ugliness; You can call methods with explicit self too. http://is.gd/dcLAZq http://is.gd/dcLAZq In this case you would pass `Foo::bar` down to iron. Assuming the arguments are in the right order. > and you can't catch them You're not supposed to. Panics are to be used as less as possible; only for irrecoverable things or for application-level panicking. > Nested structures is pain; Could you expand on this point? > Usage of safe code can lead to out-of-bounds errors, with thread panic (hello to vec macros). It's idiomatic to use iterators as much as possible, or use the monadic indexing methods (which return Option).
- kbenson 11y agoI'm not sure why this was dead, but I vouched for it. Nothing here seems remotely worthy of flagging IMO.
- EugeneOZ 11y ago> You can call methods with explicit self too. Point is "signatures are different". You can't use this function in place where you need signature without &self. > You're not supposed to It makes life of web-servers harder. > Could you expand on this point? To parse JSON with nested objects you need to declare a lot of structures. When APIs are difficult, people even use code generators. > It's idiomatic It's not an argument. What work should work. Idiomatic or not - another question.
- Manishearth 11y ago> Point is "signatures are different". The signature is fn(&Foo, u8). If that's not in the right order, you can always put it in a closure -- this is not a Rust-specific problem. > It makes life of web-servers harder. I don't see why web servers need exceptions. You do have catch_panic if you want to prevent the application from ever crashing; that's what it's for (rewrapping fatal errors at the top level or preventing panics from leaking through FFI) > To parse JSON with nested objects you need to declare a lot of structures. Fair enough. I think there was a nested hashmap based JSON library somewhere?
- deleted 11y ago[deleted]