I really appreciate the user-friendliness of Rust's error messages -- I can't remember seeing a compiler tell me "maybe try this instead?" before (perhaps something from Clang, but never with the specificity of, e.g., a suggested lifetime annotation). And from a parsing / compiler-hacking perspective, it seems really hard to get the heuristics good enough to produce the "right" root cause. Kudos to the Rust team for this continued focus!
It's taken... I dunno, 50+ years?... but it's nice to see more and more code being written that doesn't assume programmers are superhuman beings with an IQ of 250 and infinite concentration and working memory. We need all the help we can get, so that we can focus as much of our precious, limited cognitive firepower on what really matters. When even John Carmack is talking about getting all the help he can from his development environment [1], you really ought to listen.
Pair debugging is an exercise in patience that I often lose.
If I had a dollar for every time I asked someone "Okay, look for other uses of this variable" and they grab the mouse and stare at the screen because THEY'RE READING THE ENTIRE FILE LOOKING FOR A PIECE OF TEXT, instead of using any of the dozens of search mechanisms at their disposal, I could retire and write self-help books for programmers.
Stop trying to white-knuckle everything all the time, you masochistic people. Use tools like a sentient creature is supposed to.
Maybe the other person in the pair is forgetting to use their tools because they are stressed out by the aggressive person standing over their shoulder looking for any excuse to grab the keyboard?
Mostly I think the exploratory phase of debugging is a battle between your limited short term memory and your imagination. It's a think you need to do alone and without someone stopping you to ask why every fifteen seconds. I think that's why people are so big on repro steps, so they can go off and start the process of elimination without having to dump state while defending checking possibility A before checking possibility B.
I think the only reason (besides tenacity) that I fix bugs that others gave up on is that I have tricks that let me walk the code faster, which lets me make forward progress on deduction before I forget WHY I was looking under this rock in the first place. My debugging practices look not unlike a guy looking for his missing keys. You have to be careful about when to hit him for questions, and most of the time it's better to just start your own parallel search if you want to help.
> which lets me make forward progress on deduction before I forget WHY I was looking under this rock in the first place.
There's nothing quite as deflating as finally getting to the end of diagnosing a particularly pernicious bug just to have the understanding trigger the realization that you've encountered this bug before a year or two prior, spent just as much time originally figuring it out, and had somehow forgotten about it the interim. Yay for wasted days of our lives.
Whenever I unravel a hard-to-diagnose bug, my first step is always to put a better error message in the place where it would have been properly diagnosed.
Sure. I can't recall the last bug that brought this feeling (sigh, the circle continues), but I vaguely recall it being a weird interaction or behavior when interacting with some remote system, and it wasn't in fixing a bug that popped up, but in implementing a new feature or system that interacted in a similar way, but the prior implementation was either in a different project or had since been discarded. I know that's vague. That probably means I'll encounter this again and not identify it as the same problem. :/
I think I need to make a concerted effort to get more sleep.
If you haven't recognized your "old bug friend" during the figuring-out process, maybe the path that lead to the bug was different this time? I.e. you have an old bug in a new context, which is almost like a fresh new bug.
Personally, when I find out / solve something tricky I note down the details in a notes file exactly for cases like this. I'm yet to use it though, because I usually remember the weirder bugs I've seen.
I'm pretty sure it was. From what little I remember of it now, I think it was probably best classed as "weird and esoteric undocumented or wrong behavior in a remote system or API".
Sometimes, this might be the case, however after the nth time of nicely saying "oh btw you can just do [insert shortcut] and find it right away!" it's hard to not get frustrated. I have definitely worked with people who for whatever reason, absolutely refuse to learn their text editors and debugging aids.
Usually this becomes an interpersonal issue when you're working with someone who has a track record of only changing 90% of the code that needs to be changed to implement a feature/bug fix because they keep missing one spot where the information is used.
Already in late 90's I couldn't believe what UNIX coders considered state of art, versus what we had on Mac/Windows/Amiga environments (the ones I knew before UNIX).
Maybe sometimes. I've certainly worked with someone who explicitly said "if your first instinct on seeing an error is to reach for a debugger you're probably not a good programmer", and as a result he'd spend hours tracking down a bug that could be solved in minutes by someone willing to actually use tools. Even more unfortunately, a lot of the junior programmers on the project listened to him and wouldn't use debuggers either.
It's your fault for saying "look for". They're doing just that. They're using all their available brain power thinking about the code so they don't have any to spare to interpret unclear instructions. Instead say "search for", or if that's still unclear say "control-F for" (or whatever shortcut activates search).
Have you tried suggesting that exact trick (using search rather than scanning) to your pair whenever they default to the Mark One Eyeball?
Having paired quite a bit, it's rather amazing how many programmers just don't know the full utility of their existing tooling. Not because they are stupid, but just because they never made that particular connection.
I have been on the receiving end of this dozens of times, and it is one of my favorite things about pairing as a programmer: where my pair shares a neat trick that saves me a notable amount of time and/or aggravation.
> it's nice to see more and more code being written that doesn't assume programmers are superhuman beings
I would say that most compilers don't even assume the programmer is human. The root cause of bad errors is that they emanate from the compiler, and are reported from the perspective of the compiler. That's why you get errors like "can't access method undefined of undefined", or the hell that is C++ template errors. Sure, the errors make perfect logical sense from the perspective of a compiler, but they make my human eyes bleed.
My favorite is a single missing semicolon that causes a cascade of unrelated errors, none of which indicate there's a missing semicolon.
grammars, parsers, compilers, and languages as a whole should be designed for humans first. Even if it makes the language implementation a little more complex, human users will benefit greatly and thank you for it.
I'd say its hard because sometimes the errors human make would require a solution comparable to embedding a human-level AI in the compiler. That missing semicolon causing cascade of errors - sometimes it's easy to tell you missed one, sometimes it isn't. Consider following C++ code:
int foo = 2
bar = 3;
Am I missing a semicolon there? Or maybe a comma? You could probably guess it based on whether or not "bar" exists in the lexical scope during compilation, but then again, maybe I want to shadow it with a "more local" definition?
The point is - you can make suggestions based on probabilities, and maybe it is a good idea to integrate a compiler with a linter. But to actually get error messages that make sense, your compiler would have to understand what you mean.
I have tried about 5 times in my career to sit down to write a programming language. But then I see how little resemblance there is between how a compiler represents your code and how you think about it when trying to debug, fix a typo, split a file, combine two files, delete dead code.
I get in a funk and my brain refuses to push past it. I feel like Neo when they tell him about the Matrix and he pukes and passes out.
No, not if they know ANYTHING about Lisp compiler internals.
In any lisp compiler/interpreter suited for the Real World, the sexpr tree you see in your code isn't the datastructure the compiler uses. Why? Because that sexpr tree doesn't account for information like line numbers, which are needed by the compiler for error messages, and other data. The sexpr tree that macros are given is an abstraction.
As for error messages, macros make it hard to give good ones C programmers who think their preprocessor macros cause bad problems with error messages, get this: If there's an error inside a macro expansion, the compiler/interpreter is getting errors in code that litterally didn't exist in the source code in any form. Furthermore, there are the standard problems of line numbering and giving the programmer information about where the error was in the actual source, all caused by macros. And Lisp macros are far more pervasive in Lisp than preprocessor macros are in C.
Racket tries to solve this with syntax-case, but syntax-case is awkward and breaks the standard macro abstraction in a lot of ways. So the problem remains, and is fairly nasty. Although Lisps and Schemes HAVE gotten better about macro errors over the years...
Well, there's similarity, but I'd call it a ladder of representation. Your compiler represents your code as AST with some metadata and stuff. Lisp compilers do that too. Lisp source is an executable AST without that metadata, and it being executable gives you shortcuts to make the tree smaller (e.g. macros).
Want to see that in action? Look at e.g. the intermediate language between Erlang source and BEAM bytecode - it reads like macroexpanded Lisp code with square brackets instead of parentheses.
I think that is why ADA became popular for mission critical stuff as you can inform the compiler a lot more about the constraints and so in effect make the compiler more user friendly. (Disclaimer happy to be corrected as I have never used ADA but I just finished listening to the podcast on embedded.com and thought it relevant)
Ada the programming language is named after a person - the English mathematician Ada, Countess of Lovelace known as "the first computer programmer" (
https://en.m.wikipedia.org/wiki/Ada_Lovelace)
Iirc, there are multiple languages out there that were designed for the humans first.
But none of them caught on because they were either too removed from the hardware for its time, or not "macho" enough for the guys in the computer labs.
My feeling is that none of them caught on because they implemented a good idea, badly.
The way to human friendly languages is not to take the phenomenal power and precision of computer programming languages and slather on a wafer-thin English layer that fuzzes and obscures the underlying complexity. Just because you've fuzzed and obscured the underlying complexity doesn't mean you've made it go away, but in practice you generally have removed huge swathes of the power.
I'd say the sort of thing we see Rust doing here is a better path. It is one of the most demanding, detail-oriented languages there is, but this sort of error details and explanation helps the programmer through that, and what comes out the other side is someone who still has the full power of programming, but far more accessibly.
Did you post the right link? That one was about John Carmack inlining some function calls and eliminating weird branching to (potentiall) reduce bugs/errors. Or am I missing something?
Haskell has gotten really good at more or less telling you what to do, it's a pretty common technique while developing to have the compiler run in the background whenever you change a file[0]. I've found it to be great when developing because you can just let the compiler tell you what type you need to put somewhere, and you can use something like Hoogle[1] to find how you can get that type.
At the end of that spectrum (moving away from values and towards types) are languages like Coq, where you have only types, no values, and it's the compiler that derives the implementation/values from the types you define.
Like Haskell Servant[1], where you define your API as a type, and then you can derive functions from that type to query the API, because the type itself contains all the information necessary.
Coq unifies terms and types, so that all you have a terms, but there's still a very concrete meaning of value: that which can be reduced no further (normalization, a property that the calculus of inductive constructions has).
Those error messages, no matter how good, are curing the symptom not the cause. In other languages this particular problem doesn't exist in the first place.
Rust has not killed and will not kill C. Can we please cut this crap out? Rust is a cool and useful language but I am getting tired of its proponents talking smack about everything else all the time.
Not only did the user you replied to not mention Rust, as far as I can tell they are not an active Rust user. The Rust community has a clear policy against language zealotry. Your claim that "proponents [of Rust] [are] talking smack about everything else all the time" wants for evidence.
It's difficult to search for, since usually such comments end up in threads that aren't about Rust, criticizing the actual topic for not using Rust. I guess I'll have to write down whenever I see this for the next time someone complains about my complaint.
You're the person who brought up Rust in that thread. The user 'mokus', which is a handle I do not recognize from the Rust community, advocates using 'memory safe languages' over C.
So apparently you have a habit of projecting support for Rust on anyone who criticizes C?
This is very quickly devolving into a stupid flamewar, assuming it isn't already there. This is a thread about Rust error messages. When someone describes useful C warnings messages and someone follows up with criticism for C even making situations where those warnings are possible in such a thread, it's pretty reasonable to make the connection. What's your problem, dude?
Drew, you're actually wrong here. Safe systems languages predate Rust by quite a while, most of them being in the Wirth family (Modula, Oberon, etc.). Given that here at HN, we have a large constituency of Lisp Hackers and Unix Haters (as in the handbook), if somebody talks about how C is junk, and how safe systems languages should be used instead (esp. if that person is pjmlp, nickpsecurity, or lispm), they are likely referring to those, not Rust.
So not a reasonable connection to make, if you know a bit more of the context. I certainly don't blame you for making the jump, but I seem to be in the minority.
>Actually I would enjoy C, if the language just had a few things from Wirth side:
...Which is pretty much my point: You don't like C, because it didn't take from Wirth enough.
Do you have some kind of program that automatically notifies you whenever your name gets mentioned on HN? Because whenever I mention you, you show up within a day...
"Which is pretty much my point: You don't like C, because it didn't take from Wirth enough."
Close but not there yet. He doesn't like C because it ignored and still ignores basic, safety features on commonly-used operations. Wirth's stuff is often cited because it did safe one's as baseline, simple syntax/semantics, and for weak hardware. Closer to C than ALGOL, PL/0, and other languages we could cite that also had more safety. Telling a C programmer Thompson and Ritchie could've done ALGOL68 on a PDP-7 less believable than saying they could've done Modula-2 or something similar. ;)
Note: I also can't overemphasize enough that the first language they actually designed, feature by feature, to replace C was a modification of Wirth's Oberon-2 with features like we're talking about. Their Go work is indeed reducing number of crashes and vulnerabilities in systems versus C work while performing fast and improving. Imagine if they just started with Wirth's stuff then kept it practical and long-lasting (unlike Wirth).
>Note: I also can't overemphasize enough that the first language they actually designed, feature by feature, to replace C was a modification of Wirth's Oberon-2 with features like we're talking about.
No... The first language they designed to replace C was Plan9 C. Then Go, which drew heavy inspiration from Limbo, apparently.
Great analysis. The thread he links actually corroborates it, too. I've even found a few more safer, system languages since then that may be featured in future lists or threads.
To be fair to me, though, note that I also heavily promote memory-safe C (eg Softbound, SAFEcode), memory-safe UNIX (CheriBSD, SVA-OS), and user-mode UNIX (eg seperation kernels, GenodeOS) to help UNIX/C users reduce serious problems they might encounter. I just default on countering root causes of problems as first resort. ;)
I didn't know that about you. However, I would say that you probably fall under UNIX-Hater nonetheless. Not that that is a bad thing, it's merely a statement about your opinions and ideals.
I will totally have to check out some of those project now. Although I do wonder why Cyclone, the project that inspired Rust, wasn't on your list for memory-safe C.
Oh yeah, I've linked to original and ESR's interpretation of UNIX Hater Handbook. Like I said, great analysis minus that one aspect of my posts here. :)
Far as recommendations, putting my name and those terms into Google gives me six hits on HN where I recommend them both. In several, I push alternatives like microkernels, SPARK, and Rust plus those if person stays with C. In reply to ZeroTier developer, I reference Code-Pointer Integrity too while pointing out he's less safe with C++ because he can't use these C features. Ironic.
"Although I do wonder why Cyclone, the project that inspired Rust, wasn't on your list for memory-safe C."
I get 47 hits on that as I give Morissett et al's work plenty credit. Often when someone says Rust did the dynamic safety first where I counter they got it from Cyclone. Reason I don't push Cyclone so much is it isn't actively developed any more like most safer C's. C people just ignore them. Others included Safe-C, Clay, and Vault languages although I don't think all of them were OSS'd. Many non-C languages also compiled to C to get portability and performance benefits while app gets type-checked or other checks (eg bounds). Hardly any take-up there either. At this point, I just recommend them putting work into compiler extensions that make C safer with reasonable performance hits. SAFEcode already in LLVM, too.
The problem is can you name a safe systems language that doesn't sacrifice performance? Dependent types should fix most but there is no current systems language with it.
"The problem is can you name a safe systems language that doesn't sacrifice performance?"
Your performance comes specifically from not knowing your program will work upon malicious or faulty input. So, that claim is almost always apples to oranges. It's "language X let's me work and fail very fast" whereas "language Y let's me work fast." I think the 2nd one should be default option given speed of computers these days. Also, remember users' tolerance of program crashes may not be enough justification for riskier languages: silent corruption, which they don't like, can also result from unsafety.
Far as languages, the Oberons used in OS's [1] and Modula-3 [2] used in CVSup were very fast. The safe variants of C [3] were faster than inserting checks yourself given the compiler optimized some checks away with static analysis. Annotation and backward compatibility varies with each. SPARK Ada [4] can go as fast as C for static code but with provable absence of common errors. Ada, its parent, systematically [5] prevents/catches errors across whole process of programming. Rust is very CPU efficient with dynamic memory and concurrency safety. D language [6] is like a better C++ without C's risks. Fast as Free Pascal last I saw. ATS [7] is a programming-with-proofs language that uses dependent types to prove safety. It's been used on a 8-bit MCU. Finally, you can use typed, assembly languages [8] if performance really matters that much to you. Some academics & companies also mock-up assembly's in things like Rust, SPARK, etc to leverage their analyses with extraction to actual ASM.
I don't want this to be either a flamewar or stupid. The Rust community has a strong commitment to be welcoming and inclusive, and this means we try very hard to discourage bashing other languages (who could want to join a community that is constantly talking trash about the language they work in every day?). Despite this, a meme has been spreading, mainly among C programmers, that the Rust community does go around bashing other languages. This meme harms the work our community is doing and is not supported by evidence.
Also, I find the criticism of C you responded to quite valid, not "talking smack." It is a problem with C that it has several basic functions which are deprecated for security issues. This is a problem that C has much more than most other languages.
I don't think the issue was that you made a connection to Rust. The issue seems to be that you used it as an excuse to rant about a tangent with an aggressive tone in article that will attract proponents of the target of your rant.
In other words, it didn't devolve into a flamewar, because that's where you started it out.
The person you're replying to didn't even mention Rust -- and they're right that many languages other than Rust avoid the problems cited in the listed error messages.
Loads of languages have old functions that could be better with hindsight, I'd probably say all of them. Some of them even have security implications (mysql_real_escape, anyone?).
C isn't going away any time soon, and there's no value in decrying it as a response to being told about a feature that makes it safer!
"Although the first edition of K&R described most of the rules that brought C's type structure to its present form, many programs written in the older, more relaxed style persisted, and so did compilers that tolerated it. To encourage people to pay more attention to the official language rules, to detect legal but suspicious constructions, and to help find interface mismatches undetectable with simple mechanisms for separate compilation, Steve Johnson adapted his pcc compiler to produce lint [Johnson 79b], which scanned a set of files and remarked on dubious constructions. "
"Loads of languages have old functions that could be better with hindsight"
Strawman. C's predecessors did it better with foresight. One of best such systems was built by C's inventors. BCPL author and C inventors deliberately removed safety at OS and language level due to hardware constraints plus personal preferences. Then nobody changed it to avoid work or broken apps. Hindsight aspect has nothing to do with it.
"C isn't going away any time soon, and there's no value in decrying it as a response to being told about a feature that makes it safer!"
Got mixed feelings on when to slam C or help its users out. I agree with you that bashing it at a comment on a safety improvement is probably a bad idea. It might have effect of reducing number of people promoting safer C strategies. I usually ignore, upvote them, or mention stuff like SAFEcode/Softbound depending on what's in comment. I go anti-C when misinformation shows up or on more general topics of safe, efficient apps.
> Got mixed feelings on when to slam C or help its users out.
All the same coin to me. Decry C, laud the tools that make it safer, and sympathize with the poor bastards stuck with it all in one breath. I C++ for a living - you may pity me too. Games, you know.
> It might have effect of reducing number of people promoting safer C strategies.
It might have the effect of increasing the number of people promoting safer programming strategies. Maybe not contributing to the depressing statistics on buffer overflow CVEs by writing their startup's entire serverside stack in vanilla memory-unsafe C. Why, they could even use some kind of LISP variant...
(yes yes, here's some tinder, may any and all do with my strawman as they please...)
" I C++ for a living - you may pity me too. Games, you know."
I've had the displeasure of dealing with it myself. So, a little bit. It can give you a bit of extra safety and flexibility with acceptable performance. Side effect, as I noted for ZeroTier, is you forfeit almost all the static analysis, memory-safe compilers, and other goodies for C language. You're in the category that might benefit from experiments with Rust given it's the C++ competitor, but with more safety. Maybe those ridiculous bugs I see in AAA titles will go away without much extra QA. Nah, I'll be unlucky and they'll be algorithmic. ;)
" Why, they could even use some kind of LISP variant..."
That's so 90's. Next you're going to want them to try to round up all the hackers, programmers, and VC's on one discussion forum. Can't expect people to pull that kind of stuff off. Far as LISP, check out PreScheme: static LISP w/ manual, memory management and compiled to C at first. Got mathematically verified during VLISP project. Enhancement of that could do games or startups. (taps head)
Actually, CARP Lisp is doing that with Rust-style safety if I recall. Has active contributors with an OpenGL snippet as demo:
strlcpy is also somewhat crap, it returns the length of the source which if I do strlcpy(d, s, n) where s is long and n is small you get to pay for finding the nul terminator in s.
I'm quite new to a lot of the concepts in Rust, and while many error messages are simply infuriatingly confusing.. there are many that are extremely helpful.
Hell, just the underline showing you what area is wrong really helps you spend the fewest cycles on simple typos and etc. It's really a joy.
Fwiw, the frustrating times are usually involving some semi-obscure type system issue i've caused. But seeing as i'm probably their target user for these sort of messages (beginner), i guess my issues are still probably relevant.
Not yet. Adding warnings is tough; some part of the ecosystem compiles with "warnings == errors", and so adding new lints can cause ecosystem breakage.
Crates.io should have a check for things that get published to it that objects if you try to upload something with `#![deny(warnings)]` on the crate. It’s fine for your own code, but production libraries should never use it.
I don't know if I've seen it in compiler output, but I've seen IDEs like Eclipse and XCode have some pretty good "fix it for me" suggestions (maybe those are sourced from the compiler, I'm not sure).
In my little rust experience the suggestions the error messages had, even in the longer explanations, were useless. Mostly it came down to me trying to do something that was simply not supported, but the compiler not knowing that and leading me on a wild goose chase.
From what I remember, I was trying to use the iterator trait, but return records that contained str pointers.. The goal being to parse a file and yield pointers to the strings from each line to avoid allocating memory and copying bytes around. Rust tries to tell you that you need lifetime specifiers, but if you try adding those nothing compiles anyway because the iterator stuff doesn't actually support that.
I eventually got it to work by returning copies of the strings.. maybe the unsafe stuff would have done what I wanted, that's what rust-csv seems to do at least.
I concluded that Rust is definitely not a language you can learn by chasing down error messages and incrementally fixing things. If you don't 100% understand the borrow and lifetime stuff, fixing one error is just going to cause two new ones.
though in my case I had a vec of &str or something like that.
What I do remember was the compiler sending me in circles. Honestly if it had just said something like "Hey dummy, you can't do that, go read the chapters on lifetimes again" I might have fixed it. But it kept telling me things like "Just add a lifetime specifier on this line" and I would do that and then get 2 more error messages. I think the errors sent me down the path of trying to do what the SO post mentions, which is
fn next<'a>(&'a mut self) -> Option<Vec<&'a T>>
instead of putting the lifetime on the impl block, which probably never even occurred to me was something you could do.
Ah ha, yes, this is more than just pointers. It's a "streaming" iterator as opposed to just an iterator, and yeah, we need more types, IIRC, before that's possible.
As I mentioned below, we love bugs about bad error messages, feel free to file them!
The idea here is to separate lifetime of iteration (the scope in which "next" is used 'i) and the lifetime of data ('a), which would result in following signature:
Please, take those complaints from others seriously.
There are plenty of tools that help people (including myself) to deal with compiler errors more easily, and they're not limited to emacs either.
For most purposes, having at least _one_ line in the standard 'filename:linenumber:[column:] {error,warning,...}:' format is sufficient for compatibility. You have such a line already; just remove the '-->', add the 'error:' or whatever back in, and you should be good to go without sacrificing any of the (very welcome!) improvements from this change.
The repetition is not what I was speaking of. As you say, including the same file name N times with successive line numbers just because you've localized the error somewhere in that span means a bunch of noise.
But where you are going to include a file location (and one is included), put it at the beginning of the line, to be friendly to existing to existing tooling. Putting the "-->" in front of the location is not what makes this format more readable.
(Including multiple locations is great where they are actually distinct locations.)
All I want is for C-x ` to work in Emacs's built-in compilation-mode. As long as the new error reporting doesn't break that, I and the other Emacs "M-x compile" users will be happy campers.
Agreed. Get a dozen errors at once and you can feel your eyes glass over from all of the repeated file names. Better to just update the error parser in emacs.
I actually agree about the repetition. I was speaking to formatting of the file locations that are included.
Far better to remove (or move) for characters, than to update every tool to handle yet another format (and/or increase false positives in detection of src locations in an error stream).
Personally I care about vim (and some scripts I have), but I do think emacs assumes errors of the same format. It's generally easy to work with, and output by a lot of things (including [git] grep -n).
For my use, what I care about is that important locations that I might want to visit appear at the beginning of the line as either "filename:line:col: " or "filename:line: ".
Other lines can begin with "error[E0080]" - that does no harm.
If others have more particular needs, I hope they voice them. (nhaehnle seems to want severity following location?)
I would love to see an option for showing the error order forward or backward. My workflow is to start fixing compile time errors from the top of the `cargo` output but scrolling to the top can be fairly annoying when there are a lot of errors. Having the most relevant error at the bottom of the command line (where it automatically scrolls) would be useful as an option IMO. This probably causes some other unseen problems however
Well, I just use 'more' or 'less' to see the beginning of the output. I'm also using GNU screen, and can easily scroll back through the terminal's history if I can't be bothered to re-run the command with a pager on the output.
I sometimes do that, but the output loses the color it had, which can make parsing it a bit tricky (although the less noisy new format will help a bit with that)
This only helps if the program that pipes into less doesn't do terminal detection to decide that it doesn't want to output ANSI color escapes into a pipe (to less).
You may sometimes be able to work around this by using `expect` which creates a pseudoterminal attached to the program's stdout instead of a pipe. For example, say the program you want to run is `ls --color=auto`. This produces color when stdout is a terminal but no color when stdout is a pipe. If we just did:
ls --color=auto | less -R
we'd see no color. Instead we can run ls under expect:
expect -c "spawn -noecho ls --color=auto; expect" | less -R
and color abounds.
There may be an easier way to accomplish this. If anybody has ideas, chime in.
This partially works for me with "cargo test"; it also seems to print a control character ('^O') after every colored string, as well as at very beginning of the output. Additionally, after a certain amount of output (maybe 1.5 times my terminal height), it prints an ellipsis and stops printing anything new.
Thanks a bunch for pointing me towards `expect`, though! I hadn't used it before, and I'll definitely do some experimenting with it to see if I can get my desired output with it.
cargo build --color always | less -R should work with recent cargo, alternativly `cargo rustc --color always -- --color always 2>&1 | less -R` works as well.
Very good! I always liked the content of Rust's error messages as it clearly explained the issue, but the form of those error messages was a bit problematic, they were very noisy and it wasn't easy to see the issue by simply glancing, you had to scroll up, find the beginning of the error and read carefully.
I always love it when we bring UX to the the tooling we use, and not just on the end product in our users' hands. Everyone appreciates a delightful UX, including software engineers. I've been eyeing Rust for a while now, this just gives me another excuse to hack with it.
I love the clarity and readability of these errors. You can work on UX at lower levels, and it looks like this. Beautiful. I'm not even a Rust dev, I'm mostly in C# land these days, but I appreciate the effort this takes. Well done!
Better ways to display non-local problems. Rust's borrow checker detects many errors that reflect inconsistency between two places far apart in code. This is hard to display.
I've been working with Elm over the last week, and the error messages are informative and helpful. When, possible they educate you on the nature of the error and guide you on how to fix the problem.
This is great! Why keep the row/column numbers at the end of the source file though? Aren't they redundant (IDEs shouldn't be parsing command line output anyway so they don't need it).
This focus on compiler usability is really fantastic. C calls these "compiler diagnostics" for a reason - they should help the programmer diagnose and fix the problem. I loved it when Clang started making C errors sane (and getting GCC to introduce better messages too!), and I'm glad to see Rust take the next step. Since I'm stuck in C++ for the time being, I'm (selfishly) hoping that Clang takes a page from these new Rust errors - these sorts of diagnostics would look great on C++!
Not related to this article, but I was looking through the Rust survey mentioned at the bottom of the article and was surprised at the amount of people using it for web development.
I'm not very knowledgeable about Rust but I guess I assumed it would not be the best technology to use in that space. Is Rust really that prevalent in web development?
That's mainly my goal as i learn Rust. It's been a difficult learning process[1], but i persist because the code i write feels simply more correct. I also think as time goes on frameworks will improve the ease of use, much of the ecosystem is very young.
Even better (or more crazy, heh), i plan on using Rust for clientside as soon as we have a feasible Rust -> DOM api bridge.
[1]: My learning process was mainly involved in the type system, when writing my own libraries. Not so much to do with basic web development.
That looks really cool and I'll have to give learning Rust another try when this lands. Also, the title was pretty wonderful. I spent a bit thinking about it before looking at the domain and realizing what it had to be.
Yes, current nightlies are 1.12. Anything can happen before release, though, so in theory, it's not guaranteed to land in 1.12 until the day that 1.12 forks off from master.