19 ms·
My Struggles with Rust
- ungzd 9y agoI don't think it should be as easy and concise as python — it's systems programming language without GC. It is not designed to be used in place of all programming languages, just in place of C and C++.
- pornel 9y agoThese struggles are real. I don't see a way around them other than just learning them (and then they go away, because you know what code won't work, and don't fight it). It's probably because Rust looks and operates mostly like a high-level language, but still satisfies low-level constraints. e.g. the confusing difference between `&str` and `String` is equivalent of C's `const char * str = ""` vs `char * String = malloc()`. In C if you had a code that does: char *str = foo(); free(str); you'd know that in `foo()` you can't return `"error"`, since an attempt to free it would crash the program. And the other way, if the caller did not free it, you'd know you can't have a dynamic string, because it would be leaked. In Rust you don't see the `free()`, so the distinction between non-freed `&str` and freed `String` may seem arbitrary.
- rvense 9y agoThese struggles are indeed real, but at least as far as verbose error handling goes, remember that Rust is forcing you to handle a lot of things that are silently ignored in Python. Truly equivalent Python code would include a bunch of exception handling and checks for nil.
- nathan_f77 9y agoI haven't done much Rust, but why isn't there a safe way to do some of this implicitly? If you don't want to think about errors and just want to crash, then I feel like there should be a sane way to crash the script with a default error message. Could you write a thin abstraction to achieve this? Maybe there could be a new crate called "rust-script" or something, where the goal is to write code as easily as Python or Ruby. Again, I'm not a Rust developer, but it's not hard to imagine an abstraction (or even a transpiler) that makes it easy to read a file, parse it as JSON, and do something with the data.
- AsyncAwait 9y agoThere's unwrap() and panic!, does that not do what you want?
- bombless 9y agoYour answer is simply `unwrap`. OP know it but struggles to believe it, it's that simply.
- rvense 9y agoAs the other comment says, that's exactly what's done with unwrap and try. You do obviously have to write that out, but on the other hand that means you know where to add the error handling when you come back after the fact. It might take a little getting used to, but it's a decent compromise. I'd say it's a matter of taste, but yeah, there are a few more characters there.
- MichaelGG 9y agoCouldn't there be an opt-in Deref for Option and Result? Then you could just pretend everything unwrapped fine.
- leshow 9y ago> If you don't want to think about errors and just want to crash, then I feel like there should be a sane way to crash the script with a default error message. We have `expect` it's like unwrap(), but takes a string. When the program encounters some error, it will exit and print the string.
- cowsandmilk 9y agoThe author seems to want to not use unwrap() in the rust version when that is basically what is done in the python version. The python version will die with an exception if: 1) the file does not exist 2) the file is not readable 3) the file cannot be parsed Rust forces you to say you want to panic in these cases (by using unwrap), but beyond that, the behavior is similar.
- amelius 9y ago> It's probably because Rust looks and operates mostly like a high-level language, but still satisfies low-level constraints. In an ideal language, you could decide to ignore low-level constraints and your code would work just fine, although perhaps less efficiently.
- Veedrac 9y agoRust is targeting an audience where silently degrading performance is problematic.
- vbezhenar 9y agoExceptions are the best way to handle errors. You can either handle them everywhere or ignore them and they'll rewind the stack. Unfortunately Rust and Go decided to use return values, instead of fixing problems with exceptions, which is step back, IMO.
- pmarreck 9y agoI agree with you but until there is an empirical basis for our opinion-probably-honed-by-years-of-coding, these 2 languages will just continue to chug along without real exceptions My argument would be this: What is a runtime exception, really? It's a state that the programmer did not handle (either due to lack of thoroughness or flaws in mental model). Suppose the error is just ignored: To this I ask, why would you ever want code to continue in some state that has gone off the rails of determinism relative to the mind of the programmer? Imagine a bug that goes undetected because the corrupt state it generates only becomes a real problem many stack levels later under some corner case. Can you imagine a more hellish debugging scenario?
- hashhar 9y agoI have run into something very similar in somebody else's python program where they declared a string that was later used (based on some conditionals) to locate a file. The thing is that most of the conditionals were never hit under ideal conditions (like passing all args etc.). It took me a lot of time to track down the bug (also because of the lack of awesome debuggers for Python).
- tyingq 9y agoI don't know Rust, or the general direction of the community around it. Is there some chance, that over time, most popular functionality will end up in well architected crates that abstract away some of these complaints? A bad example, perhaps, because they probably go too far with it, but a lot of java's verbosity fades away because there's a rich ecosystem of libraries that already know how to do what you're trying to do. There is, of course, a downside to that...important implementation details become opaque to the users of these libraries.
- eximius 9y agoThere is currently an effort to make Rust more 'batteries included' by auditing and improving many of the most commonly used libraries (emphasizing crates outside of std).
- leshow 9y agoThe was an easy solution that he failed to use. His return type could have just been Result<MyConfiguration, Box<Error>> and he could've used try!/? freely
- Inufu 9y agoMy main gripe with Rust so far has been the unnecessary profusion of Result<> types, making it hard to process and forward errors. Case in point: the example in the article from the rust documentation that converts errors to strings just to forward them: https://doc.rust-lang.org/book/error-handling.html#the-limits-of-combinators https://doc.rust-lang.org/book/error-handling.html#the-limit... In practice, I find a type like Google's util::StatusOr (https://github.com/google/lmctfy/blob/master/util/task/statusor.h https://github.com/google/lmctfy/blob/master/util/task/statu...) a lot easier to use (I've written >100kloc c++ using it). This uses a standardized set of error codes and a freeform string to indicate errors. I've yet to encounter a case where these ~15 codes were insufficient: https://github.com/google/lmctfy/blob/master/util/task/codes.proto https://github.com/google/lmctfy/blob/master/util/task/codes...
- pornel 9y agoWith the addition of `?` operator I think it's no longer the problem. It keeps error handling explicit, but the syntax is small enough that it doesn't make code noisy or tedious to write. Note that you can also make your functions return `Box<Error>` which works like a base class for all common errors, so you don't have to worry about converting error types.
- Inufu 9y agoSure, but if you want to actually check for some error condition (say distinguish between file opened ok, file not found, or some other error) - which is the whole point of having an error type to begin with, otherwise you could just use optional - you still have to look up the definition of the actual error type used every time. A standardized error type used by everything removes that need - I know I can just call util::IsNotFoundError(..), no matter which library I'm using.
- kancer 9y agoYou may be interested in something like https://github.com/tailhook/quick-error https://github.com/tailhook/quick-error. It lets you easily implement From traits for errors so that you can convert between error types.
- tinco 9y agoBeing able to port a 20 line Python script to a 20 line Rust is the holy grail. Surely Rust has the ambition to one day achieve that, but it is by no means the main priority nor the original design goal of the language. Justin criticizes the file_double function, it being complex with nested maps and conditionals. All of this complexity is also in the Python code, just hidden away in abstractions, the library and the virtual machine. Rust, right now, is still very explicit and revealing of inherent complexities. This code is exactly why you should use Python and not Rust for this kind of little script. One day the Rust developers hope Rust will be comfortable enough for you to consider using Rust in this situation, but it won't be soon. The point gets softened a little by the remark that it probably would not be a picnic in C either, but I don't think even that is true. C still allows you to be very expressive, it would not encourage using those maps or even half of those conditionals. Rust is just that more explicit about complexity. That said I honestly believe Rust is the best thing that has happened to programming languages in general in 20 years. Rust is rocking the socks off all the non-web, non-sysadmin fields, soon its community will make good implementations of almost every hard problem in software and Rust will be absolutely everywhere.
- chillingeffect 9y agoRust hasn't made significant incursions into math modelling or industrial processing. It's advantages are slim there. Embedded will fracture into network interfacing and realtime where user input is less hostile, more predictable and doesn't require extensive constraint.
- e12e 9y agoIsn't it this kind of thinking that leads to sql injections in number plate readers?
- bmh100 9y agoI'm hoping for matrix/tensor primitives, like Fortran. Rust might be a good replacement. The C interop would also be useful for Fortran interop. What do you mean about industrial processing? PLCs?
- 9y ago
- dep_b 9y agoThe big question is would the Python script crash or handle the error when obvious problems like not valid JSON or file not found happen? My experience with Swift vs Objective-C is that clean Swift is crash free but more verbose when all other things are equal. If you don't need that level of security because it's just a small script Python was the right choice.
- doubleplusgood 9y agoIt would just raise an OSError/IOError/TypeError/ValueError and exit (unless caught).
- hasenj 9y agoIt would crash but would print an error message along with a stack trace. The rust version will probably just crash with a confusing error.
- wtetzner 9y agoWhy would the Rust version crash? The compiler will warn you if you if you haven't used a result type, and it's up to the programmer to decide what to do in the case of an error, just like when handling an exception. If you were going to use the JSON result for something, then you are forced to check if the result was Ok or Error. The only time you'd get a crash is if you just called .unwrap(), and even then you'll also get a stack trace.
- burntsushi 9y agoNote that you only get a stacktrace if you set the environment variable `RUST_BACKTRACE=1`. Otherwise, you get a standard panic message. The message from `unwrap` is probably unhelpful, which is why a lot of folks advocate using `expect`.
- hasenj 9y agoI think the point of the question was that in Python errors can still happen but they tend to get ignored when writing small scripts. So if one were to explicitly ignore errors in Rust how would the resulting program's behavior differ from the Python version?
- thegeomaster 9y agoThe `error-chain` crate [1] exists to get rid of precisely the error handling boilerplate the author has encountered. That's not ideal, though, as I believe that a place for such functionality is in the core language, not a separate library, but it gets the job done. As for the `let mut file` bit, that makes sense to me: a file in the standard library is an abstraction over a file descriptor in the operating system, and the descriptor has a file pointer which must be advanced when you read from it. I don't consider it internal state; the read operation will return new data every time, so it's not a pure function. It follows that in order to behave that way, it has to depend on some pretty explicit state. As the other comment said, Rust needs to make some trade-offs, because you simply can't have an expressive and easy-to-use language that runs so close to the metal and is aimed at being C++-level fast. As such, Rust will never be as easy to write as Python, and for scripts like the author mentioned, I'd say that Python is a much better choice than Rust. Rust is, by design, a systems programming language and it does have complexities and gotchas that arise from the need to have a lot of control of what actually happens at the machine code level. If we had a Sufficiently Smart Compiler(tm), of course, you wouldn't have to worry yourself about those low-level details and just write what your program needs to do and nothing more. However, in the absence of such an ideal, we must accept that a high-level abstraction must always leak in some way in order to let us control its operation more closely to get the performance we need. In my opinion, it's much better that necessary abstraction leakage is made a deliberate part of the API/language and carefully designed to minimize programmer error, and Rust, I think, does a good job of doing exactly that. That's not to say that the language cannot be made more ergonomic. For one, I think that rules for lifetime elision are a bit too conservative and that the compiler can be made smart enough to deduce more than it currently does. I'm also excited about the ergonomics initiative, and I hope that the core team will deliver on their promises. In general, as someone who's written more lines in C/C++ in my life than any other language, I'm very excited about the language as a whole, as I think it provides the missing link between those languages that are expressive, high-level, and reasonably safe but slow, and those that are fast, low-level, a bit terse, and allow one to shoot oneself in the foot easily. [1]: https://crates.io/crates/error-chain https://crates.io/crates/error-chain
- JoshTriplett 9y ago
- vfclists 9y agoUse Nim
- Symmetry 9y agoThe author was using this as an opportunity to learn Rust so while it might look sort of crazy to use a systems programming language for build failure notification there was a reason behind their decision. Nim is a lovely language but in the author's case he doesn't really care about speed for the use case so if they were being strictly pragmatic they could have just stuck with Python.
- vfclists 9y agoWhat!! Just as I was responding another of my hard earned points got deducted Who are these mean Rustaceans? Is Nim considered such a threat to Rust?
- SyrupThinker 9y agoI guess people consider your comment not really helpful. Everyone could come into this thread and write "Use <favorite language here>". If you'd have provided some good advantages of Nim in this case, or in general added to the discussion at hand, you might have gotten less downvotes. Maybe you want to stop attacking a community directly, aswell... last time I checked this site wasn't Rustacean only.
- CJefferson 9y agoYour post provided no content. Why should I even look at nim? I don't have time to look at every new language that comes along.
- vfclists 9y agoDoes that warrant being deprived of 2 of 190 or so points thereof of my hard earned karma? Not that I am suggesting that you are the "hater" here.
- 9y ago
- cousin_it 9y agoRust's aversion to exceptions is exactly like Go's aversion to generics - a strongly held position that doesn't actually make anyone's life easier.
- jimktrains2 9y agoI find result types to be much easier to understand and work with than exceptions. Result types can be handled by the type system, even when you have checked exceptions in java, there are still exceptions that aren't checked, and the syntax for the checking becomes monstrous.
- vbezhenar 9y agoImplicit return codes (e.g. return int, -1 means error, 0+ means OK) are equivalent to unchecked exceptions. Explicit return codes, where you must process them or compiler will yell at you are equivalent to checked exceptions. I think, that checked exceptions are a good idea, but they must be improved. E.g. Rust have syntax for almost implicit converting one error to another and return it; checked exceptions could use similar approach, so you can declare another exception in your "throws" cause and compiler'll generate conversion code for any unhandled checked exception. Anyway for me exceptions are way easier to work with, than return codes.
- jimktrains2 9y agoYes, exceptions are better than return codes, but I would argue Result types are better than exceptions. Checked exceptions in Java have their issues. Exceptions in C++ are odd beasts (though that's getting better, they're still not checked and therefor basically anything that isn't noexcept can throw them (oh wait! noexcept can throw! it just crashes immediately)).
- quicknir 9y agoThat equivalence is false. An unhandled exception bubbles up. An unhandled return code is ignored. This was exactly one of the biggest arguments against return codes.
- p0nce 9y agoHopefully some mechanism to handle exceptional cases at the language level will be invented soon.
- dbattaglia 9y agoI was under the impression that the (somewhat) verbose syntax for error handling and memory management via the type system was a necessary side effect of Rusts entire point of existence: a compiler-guaranteed safe systems language. Neither Python nor C force you in any way to pay attention to errors, making simple scripts much easier to write. I guess I'm just surprised people think that Rust should be as simple to use as Python. Maybe I'm wrong.
- ajross 9y agoI think the complaint is more that Rust has seemingly tried very hard to make error handling "simple". But in the process it has managed to invent a whole series of new idioms and special syntax that is alien to pretty much everyone. There's a thread in /r/rust about this same article where you can look and see people suggesting all sorts of ways to write this that are split into clear sedimentary layers depending on when the writer learned the language. At this point the cognitive load required to read and understand Rust implementations of "typical" practical problems is rather higher than it is for C++. And it seems to be getting steadily worse from my perspective on the outside.
- burntsushi 9y ago> There's a thread in /r/rust about this same article where you can look and see people suggesting all sorts of ways to write this that are split into clear sedimentary layers depending on when the writer learned the language. As someone that participated in that conversation, I think that's a pretty inaccurate characterization of it. It's not about when the writer learned the language, but rather, what problem you're trying to solve. If you'll allow me to summarize very briefly (perhaps at the expense of 100% accurary): * Use unwrap/expect when you don't care. * Use `try!`/`?` with Box<Error> in simple CLI applications. * Use `try!`/`?` with a custom error type and From impls in libraries. * Use combinators (e.g., map_err) when you need more explicit control. You might imagine that you could use any number of these strategies depending on what you're trying to do, which might range from "a short script for personal use" to "production grade reliability." All of this stuff was available at Rust 1.0. (Except for `?`, which is today an alias to `try!`.) It all falls out of the same fundamental building blocks: an `Error` trait with appropriate `From` impls. The one exception to this is that, recently, there has been a surge in use of crates like error-chain to cut down on the code you need to write for defining custom error types and their corresponding `From` impls. But it's still all built on the same fundamental building blocks.
- erickt 9y agoHello Justin Turpin! Sorry to hear your struggles with rust. It's always going to be a bit more verbose using rust than Python due to type information, but I think there are some things we could do to simplify your code. Would you be comfortable posting the 20 line code for us to review? I didn't see a link in your post. Anyway, so some things that could make your script easier: * for simple scripts I tend to use the `.expect` method if I plan on killing the program if there is an error. It's just like unwrap, but it will print out a custom error message. So you could write something like this to get a file: let mut file = File::open("conf.json") .expect("could not open file"); (Aside: I never liked the method name `expect` for this, but is too late to do anything about that now). * next, you don't have to create a struct for serde if you don't want to. serde_derive is definitely cool and magical, but it can be too magical for one off scripts. Instead you could use serde_jaon::Value [0], which is roughly equivalent to when python's json parser would produce. * next, serde_json has a function called from from_reader [1], which you can use to parse directly from a `Read` type. So combined with Value you would get: let config: Value = serde::from_reader(file) .expect("config has invalid json"); * Next you could get the config values out with some methods on Value: let jenkins_server = config.get("jenkins_server") .expect("jenkins_server key not in config") .as_str() .expect("jenkins_server key is not a string"); There might be some other things we could simplify. Just let us know how to help. [0]: https://docs.serde.rs/serde_json/enum.Value.html https://docs.serde.rs/serde_json/enum.Value.html [1] https://docs.serde.rs/serde_json/de/fn.from_reader.html https://docs.serde.rs/serde_json/de/fn.from_reader.html
- djhworld 9y agoThe author doesn't really justify why he needed to port the python script to rust in the first place. Pulling down some JSON, doing a bit of transformation and sending alerts seems like a perfect candidate for a high level language, I don't see any reason why you would port it to Rust unless you had significant performance concerns
- burntsushi 9y ago> The author doesn't really justify why he needed to port the python script to rust in the first place. And they don't need to. When I first learned Rust, I tried to write a `filter` function. Why would I ever do that? I could write `filter` much easier in Python, or heck, just use the `filter` method on iterators that is already in the standard library. I did it because I saw it as an opportunity to learn. I wanted to connect something I knew (`filter`) with something I didn't know (Rust).
- djhworld 9y agoI guess I was getting at the fact that porting the python script that does something very simple is the wrong tool for the job. A good candidate for trying to learn Rust is to find a script or tool that currently has the problems that Rust claims to fix.
- burntsushi 9y agoWhen someone comes to me and says, "I just spent the weekend porting a simple Python web crawler that was working just fine to Rust, and I came across problems x, y and z." What do you think an appropriate response is? Should we berate them for "choosing the wrong tool for the job"? Or should we ask them what they're problems were and help them fix them? I'm not saying we shouldn't have a conversation about which-tools-are-appropriate-when, but when someone is obviously trying to learn, let's put that on the back burner.
- omginternets 9y ago>I don't see any reason why you would port it to Rust unless you had significant performance concerns To learn Rust in a well-controlled environment? Isn't that the usual/sane way to learn a new language? Take something trivial you understand well from language A and port it to new language B? Note, of course, that this doesn't imply the result should be put into production.
- liveoneggs 9y agoIsn't nim built for pythonists to do just this sort of thing?
- mikebenfield 9y agoI think Nim may be the most underdocumented project I've ever used. I spent a week or so with it, but quickly grew extremely frustrated as I was constantly scouring old forum posts to learn how to use the basic features of the language. That is not a tolerable situation for me.
- scriptkiddy 9y agoI've been working with nim on some toy projects recently myself. I don't think there is a lack of documentation so much as there is bad organization of the documentation. Pretty much everything in the language and it's standard library is documented somewhere. You can use the documentation index to find it. Here are some links you may find useful if you decide to try again: Documentation index: https://nim-lang.org/docs/theindex.html https://nim-lang.org/docs/theindex.html (everything) Official Tutorial: https://nim-lang.org/docs/tut1.html https://nim-lang.org/docs/tut1.html Standard library documentation: https://nim-lang.org/docs/lib.html https://nim-lang.org/docs/lib.html Language Manual: https://nim-lang.org/docs/manual.html https://nim-lang.org/docs/manual.html (information on syntax, type system, GC, etc.) Compiler user guide: https://nim-lang.org/docs/nimc.html https://nim-lang.org/docs/nimc.html Backend docs: https://nim-lang.org/docs/backends.html https://nim-lang.org/docs/backends.html (nim cmpiles to C, C++ and js) Built in templating docs: https://nim-lang.org/docs/filters.html https://nim-lang.org/docs/filters.html How to tune the GC: https://nim-lang.org/docs/gc.html https://nim-lang.org/docs/gc.html Development tools docs: https://nim-lang.org/docs/tools.html https://nim-lang.org/docs/tools.html More about the compiler: https://nim-lang.org/docs/intern.html https://nim-lang.org/docs/intern.html All of these links come from nim-lang.org's documentation page here: https://nim-lang.org/documentation.html https://nim-lang.org/documentation.html
- Recursing 9y agoI think the idea has great potential, but the absence of a strong community is killing it :(
- f1b37cc0 9y ago> import json > with open("config.json") as f: > contents = f.read() > config = json.loads(contents) translates to: extern crate serde_json as json; fn read_json() -> Result<json::Value, Box<std::error::Error>> { let file = std::fs::File::open("config.json")?; let config = json::from_reader(&file)?; Ok(config) } And > import configparser > config = ConfigParser() > config.read("config.conf") can be translated to: extern crate config; use config::{Config, File, FileFormat}; fn read_config() -> Result<Config, Box<std::error::Error>> { let mut c = Config::new(); c.merge(File::new("config", FileFormat::Json))?; Ok(c) } Difficult stuff indeed.
- stable-point 9y agoI think this highlights that while there are easy solutions to the problem the OP faced, they're difficult for a newcomer to discover. (I have been using Rust for a couple of months and I'd also have reached for serde and maybe serde_derive to solve the problem). Hopefully this is something the Libz Blitz[0] will solve with their Rust Cookbook[1]. (You could almost but not quite arrive at as simple a solution from chapters 1 and 2). [0] https://blog.rust-lang.org/2017/05/05/libz-blitz.html https://blog.rust-lang.org/2017/05/05/libz-blitz.html [1] https://brson.github.io/rust-cookbook/intro.html https://brson.github.io/rust-cookbook/intro.html
- leshow 9y agoThe curious thing is that OP linked to the error handling docs, and the solution with Box<Error> is right there.
- shadowmint 9y agoIt makes me sad to see the example. This is why I maintain `.unwrap()` is one of the worst things in rust. ...because people use it; and then say; 'but don't use unwrap...'; and then use it, and your 'safe' language then happily crashes and burns everytime something goes wrong. Blogs and documentation are particularly prone to it. Result and option types are good; but if you're gonna have unwrap, you basically have to have exceptions as well (or some kind of panic recovery), because, people prefer to use it than use the verbose match statement. :/
- zokier 9y ago> ... because people use it; and then say; 'but don't use unwrap...'; and then use it, and your 'safe' language then happily crashes and burns everytime something goes wrong It might crash, but it doesn't burn, which is kinda the point of panic. Its behavior is well defined and predictable, which is great improvement over typical C UB.
- bombless 9y agoWell if people say "don't use unwrap", they're simply wrong.
- jjnoakes 9y ago> your 'safe' language then happily crashes and burns everytime something goes wrong I'm not sure why you put 'safe' in quotes here; nothing about 'unwrap()' (or even 'panic') is unsafe in the context of Rust. In fact, it acts just like Python would in the same circumstances: print a developer-centric message out and exit with a bad return code. What's unsafe about that? > if you're gonna have unwrap, you basically have to have exceptions as well Why do you think that? unwrap() is meant to be the same as throwing an uncatchable exception; if you want to throw an exception that you mean to catch somewhere, you should be using something else. > people prefer to use [unwrap()] than use the verbose match statement People may not be aware (which will come with time) but there are more than just those two choices when it comes to error handling in Rust.
- shadowmint 9y ago
- deleted 9y ago[deleted]
- frik 9y agoRust is important, it has a great chance being a first modern native system language (memory safety). Though, I wish it has less exotic syntax. It's like C++ and Erlang had a baby. Look at modern languages with nice syntax like Go, Julia, Swift and compare it to Rust. Someone coming from C, C++, C#, Java, PHP and JavaScript has to learn a lot of new syntax twists that look uncommon and different for little reason. Sure some overly complex early syntax ideas like different ones for different pointer types vanished in newer Rust releases. Now it's probably too late to improve the syntax.
- hsivonen 9y agoIt continues to puzzle me when people think of Rust's syntax as particularly exotic. It's much closer to C/Java/JavaScript than e.g. Python or Bash are. Rust still has curly braces for blocks, uses ampersand and asterisk in ways that aren't too far from C, uses dot in a way that's not too far from C or Java and uses less-than and greater-than to denote generics like C++ and Java. Personally, what keeps tripping me up when moving between languages is either forgetting to put parentheses around "if" conditions in non-Rust languages after writing Rust or having the Rust compiler complain to me about unnecessary parentheses after writing non-Rust code. But if new languages couldn't do things like omit unnecessary parentheses around the "if" condition or improve readability by moving the return type to come after the function name, that would seem like too big of a restriction on trying to make some syntactic progress. Edit: Plus it makes sense to have types after the variable name when they are optional in most cases (and then to have them in the same order in function signatures for consistency).
- twic 9y ago> Edit: Plus it makes sense to have types after the variable name when they are optional in most cases (and then to have them in the same order in function signatures for consistency). Since you brought this up, the one thing that really (but irrationally!) winds me up about Rust's syntax is that variables are: let foo: Bar = ... ; And functions are: fn foo() -> Bar { ... } Why not use a colon for the return type of a function as well?
- kstenerud 9y agoOne thing I've found with rust is that you struggle struggle struggle trying to do a simple task, and then finally someone says "Oh, all you need to do is this". Rust has already reached the point where it leaves the world behind. Only the people who have been there since the early days really understand it, and getting into rust gets harder and harder as time goes on. Yes, there's some awesome documentation, and the error messaging has gotten a lot better. But the power and flexibility of Rust comes at the cost of it becoming harder and harder to figure out how all the thousands of little pieces are supposed to fit together. What's really needed is a kind of "cookbook" documentation that has things like "How to read a text file with proper error handling" and "what is the proper way to pass certain kinds of data around and why". Right now there's a lot of "what" documentation going around, but little that discusses the "how to and why".
- steveklabnik 9y agoThere is an active (but just started) project to write a cookbook: https://blog.rust-lang.org/2017/05/05/libz-blitz.html https://blog.rust-lang.org/2017/05/05/libz-blitz.html
- burntsushi 9y ago> but little that discusses the "how to and why" Have you read the book's chapter on error handling?[1] It's being replaced in the second version of the book, but I still plan on maintaining it as a blog post[2]. Any advice you might have to add more of what you want would be helpful. (And I ask this because I tried to attack the "how to and why" angle, so I'm wondering if I got that wrong.) [1] - https://doc.rust-lang.org/stable/book/error-handling.html https://doc.rust-lang.org/stable/book/error-handling.html [2] - http://blog.burntsushi.net/rust-error-handling/ http://blog.burntsushi.net/rust-error-handling/
- std_throwaway 9y agoHow is this problem solved for C++?
- hellofunk 9y agoThe nice thing about C++ is that it is so widely used that for just about any task you can find examples of how to do it (usually many different ways to do something), especially for tasks like this article. You will also find plenty of C example, which you could also use in C++.
- kibwen 9y agoSee also previous discussion on /r/rust: https://www.reddit.com/r/rust/comments/69i105/the_grass_is_always_greener_my_struggles_with_rust/ https://www.reddit.com/r/rust/comments/69i105/the_grass_is_a...
- deleted 9y ago[deleted]
- msangi 9y agoA common theme I find in posts criticizing Rust is that their authors take a problem they've already solved in another language, try to blindly convert it in non-idiomatic Rust and then complain because things get awkward. I think that it's important to pick the right tool for the job and to follow the patterns of the tool you're using. Is Rust the right tool for the task described in the post? Probably not, but it could still be used albeit it will always require more work than Python. What's really missing is a resource showing common problems and their idiomatic solutions.
- AlphaWeaver 9y agoWhy was the title of this post changed?
- vultour 9y agoThis is a staggeringly bad comparison, almost like comparing drawing a line in C# (couple lines) to trying the same thing in C++ (possibly 100+ lines).
- gavanwoolery 9y agoRust has stressed ergonomics of late, yet I sometimes struggle to read Rust code. Obviously, there is value in elegant code, but my question is, would anybody find value in an extremely simple language that could compete with the likes of c/c++? Does something like this exist?
- kevin_thibedeau 9y agoNim. It lets you get stuff done without having to drink the provably correct kool-aid.
- _pmf_ 9y agoGC, though, an a much, much smaller community.
- gavanwoolery 9y agogoogling "GC language" predictably comes up with mostly links to garbage collection. Do you have a link to this language?
- Varriount 9y agoThere's the Nim website[0] as well as the document describing the (soft) real-time GC that Nim comes with[1]. [0] https://nim-lang.org https://nim-lang.org [1] https://nim-lang.org/docs/gc.html https://nim-lang.org/docs/gc.html
- gavanwoolery 9y agooops, I was confused - thought the comment was talking about a language named GC, rather than the fact that Nim has GC.
- dom96 9y agoFor most applications a GC is fine. In addition, Nim's GC can handle soft real-time programs like games pretty well.
- Dowwie 9y agoFortunately, Rust gets so much love from so many that it will thrive without winning over Everyone
- alkonaut 9y agoWould it be theoretically possible to get to this? fn gimme_config(some_filename: &str) -> MyConfiguration { toml::from_file(some_filename).unwrap() }
- vfclists 9y agoThe author might consider Nim - https://nim-lang.org/ https://nim-lang.org/. It is a statically-typed compiled language that about equals Rust in performance, but has a much cleaner higher-level Python-flavored syntax, and a very Pythonic parsecfg module in stdlib. PS. To my earlier downvoters can I have my hard won karma back, please??? This is the response I have been advised to proffer after consulting on the Nim forum, after my earlier terse comment.
- yongjik 9y agoIf you're so concerned of imaginary internet points (a.k.a. hard won karma), I'd advise you to stop talking about that. Complaining about downvotes is one of the few reliable ways in HN to get further downvotes. (I mean, you could say "What? That's bollocks!" and stop caring about votes given by these mindless hordes. Or you could follow the social norm and happily gather sweet internet karma. It's up to you.)
- dep_b 9y ago> Only if the programmer chooses to not handle exceptions, which is bad practice. So basically you're telling me that the example Python script is actually considered bad practice. I didn't saw that coming, I thought it was just grrrreat without any checking. Keep the wisdom coming! > In Python you can catch an exception and continue the operation in a different manner. But he doesn't do that. > Well, you seem to not know a lot about exception handling in Python, so I hope I was at least a little helpful. snickers Come on you can't be saying this seriously?
- scriptkiddy 9y agoYou know, if you want to be an asshole, I'm not going to try and have a discussion with you. The example the author gave is not the actual script he was using to monitor Jenkins. It's a small portion of it. Seriously, if someone hasn't used Python before, I can't just assume that they know how Python's exception handling works.
- dep_b 9y agoThe guy puts three lines of Python code with no error handling whatsoever to continue complain at least half of his blog post about how forced error checking makes him jump through hoops to ignore or implement it. It seems pretty obvious to me that production level Python with actual error-handling doesn't look as simple as his three-liner. You can't compare that to a language that actually forces you to deal with it. If you follow up on the compiler hints and follow safe patterns while working in Rust (like no forced unwraps) you'll end up with very robust code, something that's up to the discipline of the Python programmer.
- sctb 9y agoWe detached this flagged subthread from https://news.ycombinator.com/item?id=14287455 https://news.ycombinator.com/item?id=14287455.
- ricardobeat 9y agoIf the goal is [fast, compiled, statically typed], a language like Crystal [1] would probably be a better fit for the author: require "yaml" config = YAML.parse(File.open("test.yaml")) [1] http://crystal-lang.org http://crystal-lang.org
- brobinson 9y agoDoes Crystal have YAML.load_file like Ruby does? Loading a YAML file only requires one method call in Ruby.
- ricardobeat 9y agoCrystal does async IO underneath, so this approach allows the use of a streaming parser (you're just passing it a file handle, not the contents).
- brobinson 9y agoCool, thanks!
- cdunn2001 9y agohttps://nim-lang.org/docs/parsecfg.html https://nim-lang.org/docs/parsecfg.html (Scroll to the examples.) An exception would be thrown on error. That exception could be trapped in a simple try/catch block. Nim is very similar to Python -- but statically typed and compiled (quickly) to machine code. There are many situations where Python is a better choice than Nim, but if you're looking to translate Python code for speed and type-safety, Nim is worth considering. And if you want to translate Python to Nim gradually, look at this magic: For calling Nim from Python: * https://github.com/jboy/nim-pymod https://github.com/jboy/nim-pymod For calling Python from Nim: * https://github.com/nim-lang/python/tree/master/examples https://github.com/nim-lang/python/tree/master/examples