That isn't a glamorous task to work on, especially if you're already comfortable with the level of editor support you have, but it helps bring more people into the community, which has a multiplicative effect.
Refactoring tools would help address compiler concerns quicker, however.
error[E0281]: type mismatch: the type `fn(_) -> _ {tool::second::<_>}` implements the trait `std::ops::FnMut<(_,)>`, but the trait `for<'r> std::ops::FnMut<(&'r _,)>` is required (expected concrete lifetime, found bound lifetime parameter )
--> src\lib.rs:53:11
|
53 | .filter(apply(second, i))
| ^^^^^
|
= note: required by `apply`
error[E0271]: type mismatch resolving `for<'r> <fn(_) -> _ {tool::second::<_>} as std::ops::FnOnce<(&'r _,)>>::Output == _`
--> src\lib.rs:53:11
|
53 | .filter(apply(second, i))
| ^^^^^ expected bound lifetime parameter , found concrete lifetime
|
= note: concrete lifetime that was found is lifetime '_#11r
= note: required by `apply`
error: aborting due to 2 previous errors
I now know why I'm getting this error. Would you?filter is from the standard lib
apply is defined as
fn apply<A, B, C, F, G>(mut f: F, a: A) -> impl FnMut(&B) -> C
where F: FnMut(&B) -> G,
G: FnMut(A) -> C,
A: Clone
{
move |b| f(b)(a.clone())
}
second comes fromhttps://github.com/Stebalien/tool-rs/blob/master/src/sequenc... which means you have to track down its implementation somewhere in macros
https://bitbucket.org/iopq/fizzbuzz-in-rust/src/920bd2bd1267...
this doesn't work, so I want you to tell me why
It would also work with a closure, but I wrote my code this way to avoid closures in the first place (I was going for point-free style).
I basically just have to write my own function:
https://bitbucket.org/iopq/fizzbuzz-in-rust/src/58bfa4c58c80...
this compiles, but it seems kind of pointless since I can only use this particular function in my case (because of the extra levels of references)
if I could use the tool.rs version, it would automatically generate all the implementations I need using macros
I had to change the `apply` function to dereference as well, that way it doesn't run into the lifetime issue. It has something to do with higher ranked lifetimes (the inability to express the higher ranked lifetime)
This is the working version:
https://bitbucket.org/iopq/fizzbuzz-in-rust/src/95451868e27f...
It sounds like you're returning closures, which is a very recent feature—it only became possible last month with the implementation of "impl Trait" IIRC. It takes time for features to mature.
Rust is a punishing language in the same way a notifying spell checker is a punishing tool. For someone used to writing without stopping and reviewing at the end, spell checking as you go might at first be annoying. After a while, you integrate it into your style, and choose the best time to deal with the errors when they come up yourself, whether that be immediately, after the paragraph/idea is expressed, or at the very end. In any case, having those handy notifications of what you need to fix is useful for a good 90% or more of the problems you might encounter.
(I don't remember similar experiences learning other languages even with strong static checks (e.g. haskell). Either my errors were 1 level deep there, or the propagation of errors (like changing a type somewhere) was easier to follow/predict to me)
I use Emacs as much as possible, but for Java dev use IntelliJ because the Java plugins I've tried were always relatively clunky. Having great language support regardless of editor sounds wonderful!
One really interesting thing about this effort is that the IntelliJ folks have their own stuff for autocomplete; they're not using racer.
Does Roslyn have the same support?
I guess JetBrains is heavily invested in ReSharper (and the underlying AST code) which would explain why they won't want to switch right away, if at all.
P.S. Regarding Java dev on Emacs, ENSIME (http://ensime.github.io) now works with java-mode rather than only Scala. I use it for Android development, and it's not perfect but works well enough.
So, yeah - the community inspired me, and I hope the RLS inspires other people to contribute to Rust and the tooling around it as well!
Within Mozilla, they can use servo as a selling point or turn to creators for help, but from the outside world, we've got so many languages available, while some might not be good when the software grow big, they are more beginner-friendly than Rust. Hence Rust needs all those tooling from the very start.
A foreknowledge of pointers helps, but for anyone for whom Rust is their first systems language, it's going to be Rust's task to teach them e.g. the stack/heap distinction, or what "aliasing" means, or why there are two string types (let's hope they're already versed in Unicode...), or how to design a system in the absence of pure OO.
C style pointer tricks are better left for level two, so to speak.
Probably a good approach teach Rust's OO way is to introduce traits as kind of extensible modules that can be composed and go from there.
It is not 100% correct, but I guess it is easier to teach than going full theory with traits being a kind of type classes and do on.
Python doesn't have complicated lifetime errors, confusing trait not being satisfied errors. Python function declarations don't need three lines of code.
I mean wtf is this?
fn accumulate<'a, T: Monoid>(tuples: &[(&'a str, &Fn(i32) -> bool)], i: i32) -> Option<T>
where T: From<&'a str>
there's about ten language features in these lines of code that Python doesn't haveI would think it's the latter, but I don't know, to be honest.
It could be T: Concatenable for all I care, but the rest of the function needs to look this way, more or less.
I only have one type parameter, that's very common. I'm abstracting over String and Cow<str> because I want to bench the performance of both. (Cow<str> is always faster)
(I don't disagree that Rust is more complicated than Python, just addressing GP's comment whether or not this is "good" rust.)
You will find examples of this mostly in libraries, but rarely its something a beginner would write. You can actually do a lot without ever using lifetimes. Eventually you'll need to learn to read this though, and its just a matter of getting used to it. I'd say none of those is any harder to understand then let say nested list comprehension in python.
I would argue that Rust has a higher learning curve overall than any dynamic language because of its type system.
That said, there are more tools to be built to make it even better. https://internals.rust-lang.org/t/borrow-visualizer-for-the-... is one extension I'm very interested in seeing.
Again, just want to mention that my point is simply that Rust needs more tooling to overcome its learning hurdles, and to me this is not a bad thing. Because once we have tools solving the learning curve problem, we can enjoy all the benefits Rust provides :)
It would help a lot in regards to language productivity.
edit: It looks like the error message changes may have been reverted (https://phabricator.haskell.org/rGHC92c924e07dfef327509555c2...) :( Sad that they reverted it instead of fixed it.
Compared to what ? Community designed languages like D, Nim, w/e - no dispute here. But corporately backed languages such as C#, F#, Swift, TypeScript, Kotlin - not really. I guess it's fair since Rust is middle ground - sponsored by Mozilla but not getting the level of investment as the others mentioned.
Rust is a community language (admittedly with the organisational backing of Mozilla), but is driving the whole ecosystem.