News for hackers. Stuff that matters.
Re:Why Rust closures are somewhat hard by amelius on Monday September 10, 2018 @04:24PM (#17954885)
I really want to like Rust.

But writing a doubly linked list was already shown to be difficult [1], and now closures are too ... It really feels like this is not a language to "get things done". Please let someone prove me wrong.

[1] https://rcoh.me/posts/rust-linked-list-basically-impossible/

Re:Why Rust closures are somewhat hard by stormbrew on Monday September 10, 2018 @04:39PM (#17955013)
Closures are a fair thing to want to be easy, but I'm not sure "can't write basic data structures that someone has already written better than you will" isn't a feature.

Truth is that one of the reasons they're "hard" in rust is because it's actually harder than people think to make a proveably correct linked list (in the absence of a cycle-safe garbage collector). It's really just surfacing a cognitive dissonance common to the programming world.

(Note for clarity: closures are also hard to prove correct in the same environment, but there's a lot more need to write them in normal working code)

Re:Why Rust closures are somewhat hard by electrograv on Monday September 10, 2018 @04:55PM (#17955114)
Additionally: Due to this, Rust will encourage you to gravitate towards pattern like immutable collections, or other 'functional-esque' coding styles. As a result, you usually end up writing code that's far more inherently reliable at runtime than something like a mutable doubly linked list. Just learning to code in 'idiomatic Rust' has made me a better coder overall, IMO, as has learning to write in pure functional languages.

I think most people definitely underestimate the amount of caution / design care required to implement even something as simple as a linked list with zero bugs, memory leaks, potential infinite loops in member functions, etc.

The Rust compiler prevents entire classes of bugs at compile time, and just requires that you to write an 'unsafe' block if you really want to go ahead with this sort of code without the compiler complaining. This emphasizes that you really do have to be careful and think through the logic and memory ownership semantics of the code you just wrote. People used to GC'ed languages will find this annoying to have to worry about at all, but that is inherently the price you must pay to eliminate GC pauses/overhead.

I'm not saying you should never use data structures that Rust makes hard to write, but that going into Rust thinking it's just going to be 're-skinned C++', or 'as easy as a GC language' is going to be a recipe for disappointment. If you allow yourself to learn a new way of thinking about low/systems-level coding, you may be pleasantly surprised. But if you're too "set in your ways" (whether it be of C/C++ or JS/Python/etc.), you're not going to see Rust's benefits.

Rust is a deeply different language than C/C++. I think people forget this, primarily because Rust is so powerful and efficient (with no inherent language overhead, allowing it to be used even in embedded environments and other systems programming tasks).

Re:Why Rust closures are somewhat hard by wahern on Monday September 10, 2018 @04:38PM (#17955005)
What's interesting is that the Rust community has turned this difficulty on its head: linked-lists are unnecessary, performance killers, and generally evil. (Ditto for trees.)

That's all true, if you squint really hard, gloss over the equivalencies, discount the additional complexity, and ignore the basic simplifying elegance of linked-lists (particularly the so-called intrusive data structure implementations). But it's dramatically overstated because of a certain defensiveness.

What is absolutely true is that cyclical referencing is the bane of static analysis, and anathema to a language that leans so heavily on its typing system for modeling language semantics. What you think that implies depends on your faith in how far type-based, lifetime-based static analysis can go toward addressing larger issues in the software ecosystem.

Re:Why Rust closures are somewhat hard by detaro on Monday September 10, 2018 @05:04PM (#17955188)
You hear fairly similar statements about linked lists from the C++ crowd too, where they're trivial to implement, so it's unlikely it's just defensive excuses.
Re:Why Rust closures are somewhat hard by whyever on Tuesday September 11, 2018 @09:31AM (#17959533)
They are are arguably about as trivial to implement in Rust. It becomes tricky when you add constraints: usually you want to avoid unsafe code, but even then you can just implement them on top of a vector and bypass any lifetime/aliasing issues.
Re:Why Rust closures are somewhat hard by jcelerier on Tuesday September 11, 2018 @05:59AM (#17958363)
> linked-lists are unnecessary, performance killers, and generally evil.

that's true on any CPU with more than 16kb of cache. linked lists were a good idea at the time of 486, not so much at the time of modern CPUs with 8+ megabytes of L3.

See https://baptiste-wicht.com/posts/2012/12/cpp-benchmark-vecto...

Re:Why Rust closures are somewhat hard by drbawb on Monday September 10, 2018 @07:36PM (#17956038)
Please consider listening to Bryan Cantrill's thoughts[1] on using Rust to, as you say, "get things done." -- In the presentation he explicitly calls out how learning Rust by trying to bang out a "trivial" data structure is very much the wrong approach. He posits that to understand the value(s) of Rust you must be willing to approach it from first principles. Let that sink in: a kernel & distributed systems programmer w/ decades of experience had to resist the urge to just bang out a linked list & instead opt to learn the language from first principles. That being said he seems to be quite[2] happy[3] with the language.

[1]: https://www.youtube.com/watch?v=aWbGPMxs0AM

[2]:https://twitter.com/bcantrill/status/1035335403186806784

[3]: https://twitter.com/bcantrill/status/1038495464692146176

Re:Why Rust closures are somewhat hard by glandium on Monday September 10, 2018 @10:40PM (#17956818)
And for kicks, here's a quote from that Youtube video you link:

"So that was a surprise. (...) I've done zero profiling on this. I've made absolutely zero attempt to make this thing faster. None. In fact, you can pretty reasonably argue that I've gone out of my way to make it slower. And we are 40% faster than my C."

Which doesn't mean that rust is faster than C, but that changing your approach can, in fact, lead to results you wouldn't have expected.

Re:Why Rust closures are somewhat hard by oconnor663 on Wednesday September 12, 2018 @12:05PM (#17970159)
Quote starting at about 1:05:00. Pretty nice :)
Re:Why Rust closures are somewhat hard by phyzome on Monday September 10, 2018 @04:36PM (#17954979)
It looks like they're different kinds of difficult. From your link:

« In hindsight and with a deeper understanding, it’s not surprising why a doubly linked list is so problematic. Each variable can only have 1 owner. If prev and next both hold pointers to a middle node, which is the owner? They can’t both be the owner. If one is the owner, another can borrow. But Rust won’t let you mutate while someone else is borrowing, so neither could actually modify the list! In general, if you have loops in your object graph you’re out of luck. »

So the solution for doubly linked lists is to write some "unsafe"-marked Rust once, really bang on it, and ship that in a crate full of generic data structures. This is acceptable to me; it's no worse than C.

With closures, it sounds like the issue is not that it's impossible, but that the lifetime and mutability analysis get tricky in some cases.

Re:Why Rust closures are somewhat hard by coldtea on Monday September 10, 2018 @05:19PM (#17955300)
>But writing a doubly linked list was already shown to be difficult [1], and now closures are too ...

That's a very shallow concern. Writing a "doubly linked list" is what you do in Rust with unsafe or will several other ways. It's also not something you usually do, you just use one of the several implementations in the library and third party libraries and get on with your actual program.

And this doesn't show closures to be that hard at all. It's the basic dynamic vs statically typed language thing, plus a couple of caveats to keep in mind. Hardly anything to write home about.

The fact the tons of people use Rust for production code already, and love it, doesn't give these concerns pause?

Re:Why Rust closures are somewhat hard by rwmj on Monday September 10, 2018 @05:31PM (#17955386)
Surely the problems behind a doubly linked list apply to similar data structures (trees and graphs, notably - of which there are many more varieties than could be covered by a standard library). Writing a tree without resorting to unsafe seems like something which would be important.
Re:Why Rust closures are somewhat hard by amelius on Monday September 10, 2018 @05:36PM (#17955426)
Yes, for example a DOM tree where every node has a backlink to its parent.
Re:Why Rust closures are somewhat hard by bzbarsky on Tuesday September 11, 2018 @05:52PM (#17963719)
In a DOM tree, any live node in the tree needs to keep the entire tree alive.

Which means you either need some sort of garbage collection setup, or reference counting (with cycle collection), or some sort of indirection where you really hold references to a "tree + node" pair and then have to worry about what happens when a node moves from one tree to another. Or something else, other than just having a bunch of objects that all point to each other without any explicit ownership semantics...

Re:Why Rust closures are somewhat hard by TheCoelacanth on Monday September 10, 2018 @07:12PM (#17955923)
Considering that one of the largest and most prominent Rust projects (Servo) is a browser, that is obviously not an insurmountable problem.
Re:Why Rust closures are somewhat hard by pjmlp on Tuesday September 11, 2018 @04:56AM (#17958129)
Re:Why Rust closures are somewhat hard by fpoling on Monday September 10, 2018 @06:05PM (#17955618)
It is trivial to implement doubly linked list. Just use unsafe.

What is difficult is to implement it in the safe Rust. But then try to proof that, say, C++, code doing the same is safe. It is very hard.

Besides, if one really wants cyclic structures in safe Rust, one can always do ancient Fortran trick and just represent pointers with array indexes. It may even be faster due to more cache-friendly memory layout.

Re:Why Rust closures are somewhat hard by oleganza on Monday September 10, 2018 @05:28PM (#17955370)
A team of three people including me have used Rust _daily_ for almost a year now for at Chain[1]. Rust is _by far_ much easier to use than C or C++ and lets us get things done with clear design, record-breaking performance[2] and utmost safety[3]. Basically, people who avoided C/C++ for years as unsafe, lacking usable abstractions and generally hard to use, switch to Rust and enjoy it.

[1] Bulletproofs crypto library: https://github.com/dalek-cryptography/bulletproofs/

[2] https://blog.chain.com/faster-bulletproofs-with-ristretto-av...

[3] https://blog.chain.com/bulletproof-multi-party-computation-i...

Re:Why Rust closures are somewhat hard by pitaj on Monday September 10, 2018 @04:39PM (#17955015)
Writing a doubly linked list isn't that hard [1], and if you're willing to do it in unsafe rust, it's not any harder than any other language without a GC.

[1]: https://www.reddit.com/r/programming/comments/7zbi6s/why_wri...

Re:Why Rust closures are somewhat hard by dman on Monday September 10, 2018 @04:46PM (#17955068)
I think unsafe was poorly named since the name discourages its use.
Re:Why Rust closures are somewhat hard by orf on Monday September 10, 2018 @05:00PM (#17955144)
I think the point was to discourage it.
Re:Why Rust closures are somewhat hard by oconnor663 on Wednesday September 12, 2018 @12:09PM (#17970196)
I think the name has done an excellent job of discouraging its use. Everyone in the community seems to agree that "contains unsafe code" is a big deal for a crate, and that taking that on when it isn't obviously necessary is sloppy.
Re:Why Rust closures are somewhat hard by 1qaz2wsx on Monday September 10, 2018 @04:34PM (#17954962)
+1. As a C++ developer with decade of experience, I'm finding Rust hard. It is a truly innovative language with a rising ecosystem that makes life of developers easier in a lot of areas. But overall the safety and performance benefits do not seem to be worth the effort if you just want to get things done. My thinking is, if you are smart enough to master Rust, and you do need tight control of memory that GC overhead is not worth it, you are probably smart enough to write safer C++.
Re:Why Rust closures are somewhat hard by glandium on Monday September 10, 2018 @10:49PM (#17956841)
> if you are smart enough to master Rust, and you do need tight control of memory that GC overhead is not worth it, you are probably smart enough to write safer C++.

As both a C/C++ developer with more than a decade of experience, and a Rust developer, I'll posit that if you are smart enough to master Rust, you still aren't smart enough to write safer C++. Not even close. Rust might enlighten you in some ways, and avoid you doing some mistakes in C++, but without e.g. a borrow-checker, there are still too many ways to shoot yourself in the foot in C++, that Rust would find at compile time, while the equivalent C++ code would fail at runtime. If you're lucky and happen to hit the error conditions when you test it.

Re:Why Rust closures are somewhat hard by nicoburns on Monday September 10, 2018 @04:56PM (#17955121)
> My thinking is, if you are smart enough to master Rust, and you do need tight control of memory that GC overhead is not worth it, you are probably smart enough to write safer C++.

Easy for you to say as a C++ developer! As someone who came to Rust as a JavaScript/PHP/Python developer, I greatly appreciate Rust checking all my work. I'm plenty smart enough to work out the problems that the compiler picks up (once I have an error message I can google for explanations and solutions), I just don't/didn't have the experience to know that my naive code was going to cause problems.

Re:Why Rust closures are somewhat hard by int_19h on Monday September 10, 2018 @05:02PM (#17955156)
Most of the issues described in the article on closures are identical to C++, or have direct C++ equivalents (it even helpfully points them out!).
Re:Why Rust closures are somewhat hard by k__ on Monday September 10, 2018 @04:35PM (#17954967)
Why do you write your own basic data structure?
Re:Why Rust closures are somewhat hard by wahern on Monday September 10, 2018 @05:05PM (#17955199)
There's a theory of programming that says software development is fundamentally a process of devising and implementing data structures specifically tailored to the problem at hand.

This theory says well written software doesn't (and can't) simply stitch together various data structure implementations through generic interfaces. That in robust, elegant software there's no dividing line between where the fundamental data structure is implemented and where the application specific logic resides.

One classic example is the Thompson NFA. The argument is that the path to devising elegant solutions like the Thompson NFA is to think in terms of simple data structures tailored to particular problems. A toolbox of pre-implemented data structures is of little value because implementation matters and often needs to be tailored to the problem. It's not a matter of performance; it's that if your data structure implementations aren't tailored to the problem your use of them will require overly complex, opaquely layered code and you would (justifiably) architect your solution some other way; a way better suited to gluing together libraries but poorly suited to the actual functional problem.

I don't think this particular theory is right in any absolute sense. But I think it's more right in the domain that Rust targets, which means I believe the cost of implementing things like linked-lists and trees is underestimated; and that how often people will end up resorting to unsafe code (or recapitulating reliance on unchecked memory access, such reinventing pointers as indexes into arrays) is underestimated.

Re:Why Rust closures are somewhat hard by k__ on Monday September 10, 2018 @05:34PM (#17955410)
Interesting assumption!

Most of my theoretical computer science knowledge was based on the fact that there are a bunch of basic well known algorithms and data structures and you build everything out of this.

Do you have resources on the approach "invent" such things on your own so they are better suited for the problem?

Re:Why Rust closures are somewhat hard by wahern on Monday September 10, 2018 @06:34PM (#17955763)
I think the idea, as I understand it, comes from reading some of Rob Pike's works and people who think like him. For example,

  Rule 5. Data dominates. If you've chosen the right data
  structures and organized things well, the algorithms will
  almost always be self-evident. Data structures, not
  algorithms, are central to programming.
(https://users.ece.utexas.edu/~adnan/pike.html)

I read about the analysis of Thompson NFA, in the context a simplified version implemented by Rob Pike, in the chapter that Brian Kernighan wrote for "Beautiful Code: Leading Programmers Explain How They Think". Kernighan and Pike also wrote "The Practice of Programming", where the simplified version was originally published. Perhaps I'm making too much of that example, but it's what popped into my head.

Basically I think the idea is that if you farm all the complex data structure and algorithmic code to generic libraries, you're not apt to wrestle with the core functional problems. What functional features are you willing to sacrifice, if any, to create a more elegant solution? You can't begin to approach such a question unless you're also thinking, in very fundamental terms, about how to implement and combine the data structures and algorithms. There's an interplay between how you model a problem and how you implement it that effects every aspect of your design--or should effect every aspect of it. Using an off-the-shelf implementation brings a different cost-benefit profile, including wrt to composition. Sometimes it's better to use off-the-shell code, sometimes not; but you have to be prepared to think holistically about the problem.

A language that makes it more painful to implement or apply certain approaches internally effects your calculus from the outset.

A very simplified example: say you have some problem where a stack data structure (i.e. LIFO) is the obvious solution. If you think in terms of using off-the-shelf code, then in a language like Rust you're going to use something like a Vec or w'ever. But if your language supports recursion atop a dynamically growable stack, then a recursive solution will often be the simpler and more elegant approach. Both are, fundamentally, using stack data structures. But how you implement the stack can make a world of difference; conversely, which approach you choose is highly dependent on the problem and on other aspects of the larger implementation.

Taking that process to its logical end can result in a language like Go, where they've taken one of the primary problems in expressing highly-concurrent tasks, expressing a multitude of serial flows of execution that dynamically branch and collapse (not unlike the Thompson NFA), into the core language. A dynamic, growable call stack is fundamental to their approach.[1] Now step back and realize that Go itself is a solution to the specific problem of writing network services. It's obvious to most people how Go has sacrificed certain use cases for the benefit of others. It's an elegant solution for its problem domain because of how they were willing to apply and layer their abstractions. How you implement generic data structures matters. Among other things, you can combine abstract data structures more creatively and more powerfully when you're implementing them with a particular, shared goal mind.

Another good read along these line is, "Passing a Language through the Eye of a Needle: How the embeddability of Lua impacted its design". (https://queue.acm.org/detail.cfm?id=1983083) It discusses how the semantics of the Lua language were constrained by its problem domain, on the one hand; and how they were made more powerful by novel implementation solutions (e.g. clever approach to compiling closures that resulted in elegant code with efficient runtime behavior), on the other.

[1] Whereas other languages, like Python, JavaScript, and C++ solve concurrency differently (e.g. using Promises or async/await) because they're limited in how far down they can push the implementation of the call stack.

Re:Why Rust closures are somewhat hard by k__ on Monday September 10, 2018 @06:55PM (#17955847)
You mean, creating your own data structures is the reason Go doesn't has genrics? Like, off-the-shelve solutions aren't optimized for the problem, so you have to write your own optized version anyway, so you don't need generics.
Re:Why Rust closures are somewhat hard by wahern on Monday September 10, 2018 @07:13PM (#17955926)
I think that's way too specific. Go lacks generics principally, AFAIU, because the designers had very specific notions about the complexity of the compiler and how that fit into the overall picture.

It true that there's an argument that says you often get more dividends for your effort wrestling with larger architecture and design than about, e.g., how easily you can write (or reuse) a binary tree implementation. A library won't help you implement the binary tree implementation for accessing a filesystem's on-disk data structures, for example. The value of some of the most beneficial use cases is often precluded to generic implementations. I think that reality played into why they discounted the value of generics, making them a low priority, but it's subtle and complex.

Generics (and meta programming more generally) cut both ways in terms of cost and benefit, at least when you think more holistically, and especially when you think about the complexity of the language and language implementation. It's a complex topic. There's no right answer, at least no right answer without a careful accounting of the context--the problems you're trying to solve and which aspects are the most critical or the most difficult to solve. That's the point.

Another way to think of it is that Go's structural typing (loosely speaking, duck typing) had much more bang-for-the-buck than generics, both abstractly and concretely. If you came to that conclusion early on, you may design and implement the language in a way that makes generics even more difficult to fit into the language. The original decision could have been perfectly legitimate, but over time it might seem like you simply didn't appreciate generics at all, especially when criticisms take the benefits of the existing design for granted without thinking about path dependency, etc.

FWIW, I've never written a single line of Go code.

Re:Why Rust closures are somewhat hard by dman on Monday September 10, 2018 @05:47PM (#17955504)
I have had to write specialized lookup tables multiple times for the problem at hand. In every case doing something custom gave non trivial speedups over existing off the shelf solutions.
Re:Why Rust closures are somewhat hard by k__ on Monday September 10, 2018 @05:54PM (#17955552)
I guess I do such thing all the time, but more or less on-the-fly.

Would be nice if there was some theory around this I could follow :)

Re:Why Rust closures are somewhat hard by tannhaeuser on Monday September 10, 2018 @05:06PM (#17955204)
Is it wrong to expect being able to implement standard data structures such as doubly-linked lists and trees with back-pointers having known complexity and performance trade-offs in a language advertising itself as replacement for a system programming language? After all, you should be able to implement standard libs in the language itself, and also to replace existing implementations.
Re:Why Rust closures are somewhat hard by steveklabnik on Monday September 10, 2018 @05:09PM (#17955230)
It is wrong to expect it to be something that you start to learn the language with. Non-beginners write data structures in Rust just fine.
Re:Why Rust closures are somewhat hard by mjewkes on Monday September 10, 2018 @04:30PM (#17954921)
A doubly linked list is not a good candidate to be written in _safe_ rust.

Lots of other problems are.

Re:Why Rust closures are somewhat hard by ramenmeal on Monday September 10, 2018 @04:35PM (#17954966)
Has there been any responses to this by some rust guru's? I don't follow rust too closely but am curious about the ownership model
Re:Why Rust closures are somewhat hard by steveklabnik on Monday September 10, 2018 @05:04PM (#17955184)
Yes, there's been lots of writing about this. I've been implementing linked lists in various ways over the last week (including right now), so this is very top of mind for me.

The core of it is two things: mindset, and how programmers think about learning languages.

Mindset: there's two things at play here. The first is that C programmers tend to reach for linked lists by default. It's a CS 101 data structure. Not super hard. A Rust programmer, however, would reach for a vector (or a deque) by default. For many use-cases, these structures are better, thanks to amortized allocations + cache reasons. As always, depends on exactly what you're doing. The second mindset issue is write vs use; C programmers tend to write their data structures themselves. Rust programmers tend to use packages. If you've determined that you need a linked list in Rust, you don't start writing one: you "use std::collections::LinkedList;". It's a doubly-linked one, so maybe that's not what you need. In that case, you go on crates.io and see if someone has already written what you need. (225 hits incidentally: https://crates.io/search?q=linked%20list) Only if that fails do you write it yourself. As the ecosystem has filled out, this happens increasingly infrequently. So "a linked list is painful to write" just doesn't apply to the vast, vast majority of Rust programmers who are simply getting work done.

Learning: because linked lists are a CS 101 data structure, they're something people reach for when learning Rust. But different languages are different, and Rust is not C. Writing a good data structure isn't a beginner Rust topic, it's an intermediate to expert one. There's stuff Rust makes easy that C makes hard as well. You can't assume that topics are equally difficult across the languages. Even then, there's http://cglab.ca/~abeinges/blah/too-many-lists/book/.

TL;DR: linked lists being painful to implement is sorta true, but also not really relevant, other than people who try to learn Rust by building them and having a bad time. (Which is unfortunate, but many people don't as well, or have at least heard that they're hard and so have the right expectations going in.)

Now, I've gotta get back to my benchmarks: std::collections::LinkedList is twice as fast as my straightforward C linked list, and I gotta figure out where I messed up. I'll check back later for replies.

(If you're interested in this benchmark I'm working on, https://godbolt.org/z/lF1D85 is the disassembly. They look so close, I have no idea why 100,000 pushes, the Rust impl is taking 7.9038 ms on average, whereas the C impl is taking 15.413 ms. That seems very wrong...)

Re:Why Rust closures are somewhat hard by Cocalus on Tuesday September 11, 2018 @04:22AM (#17958005)
Have you checked the allocator, that may cause cache differences.
Re:Why Rust closures are somewhat hard by steveklabnik on Tuesday September 11, 2018 @06:58AM (#17958578)
Since I’m on Windows, the Rust is using the system allocator, just like the C.
Re:Why Rust closures are somewhat hard by xfer on Monday September 10, 2018 @07:22PM (#17955968)
> C programmers tend to write their data structures themselves. Rust programmers tend to use packages. If you've determined that you need a linked list in Rust, you don't start writing one: you "use std::collections::LinkedList;". It's a doubly-linked one, so maybe that's not what you need. In that case, you go on crates.io and see if someone has already written what you need. (225 hits incidentally: https://crates.io/search?q=linked%20list)

Not sure why you bring this up, since sooner/later people are going to need to implement their own data-structures(and this ownership problem will surface) and being it harder to implement is not relevant to package management(after all somebody did just implement that and made it available).

Re:Why Rust closures are somewhat hard by djur on Tuesday September 11, 2018 @04:40AM (#17958077)
It's very relevant in the context of whether Rust is a 'get things done' language. Implementing a linked list is not a characteristic task of 'getting things done' in Rust, just like implementing a hash table isn't a characteristic task of 'getting things done' in Python. And when you do need to do it, implementing a data structure isn't any harder in unsafe Rust than in C++.
Re:Why Rust closures are somewhat hard by withoutboats on Monday September 10, 2018 @04:56PM (#17955120)
This is the sort of really impressively shallow and baseless analysis that makes Hacker News so enjoyable to read.

These two blog posts have really nothing to do with one another, are describing unrelated problems with unrelated things, sharing only the fact that they both have to do with the Rust language and both describe something as difficult (but meaning pretty different things by the word) and you draw a conclusion that "Rust is not a language to 'get things done.'"

I don't know how to prove that Rust is "a language to 'get things done'" - this seems like an almost meaningless qualifier - but many people (including me) are getting things done using Rust every day.

Re:Why Rust closures are somewhat hard by electrograv on Monday September 10, 2018 @05:09PM (#17955234)
I actually find that Rust is far more productive overall, when accounting for debugging time (or lack thereof) vs other languages!

It is precisely because Rust makes it difficult to implement a lot of bad ideas, that I find myself spending a tiny fraction of my time debugging Rust applications vs C/C++/others (including even high level GC languages).

I love that Rust encourages inherently reliable code, while also not stopping you from writing "unsafe" blocks in the (rare) cases where they're necessary. In fact, in every case so far where I thought 'maybe I should try an unsafe block', I started to realize that implementing this idea or data structure was actually riddled with hard memory management problems, or race conditions, etc. that Rust was preventing from even being possible at all.

P.S. Of course there's a steep learning curve to Rust at first, but it's not fair to count that against Rust -- unless you also weigh against C++ all the years it takes to really master it. IMO, Rust's learning curve is far less steep and painful than C++, it's just that many of us are biased and comfortable having already climbed the C++ learning cliff (so we tend to forget it is there, and how bad it is).

Re:Why Rust closures are somewhat hard by antaviana on Tuesday September 11, 2018 @08:00AM (#17958890)
I did a basic test Rust program: load to strings certain files in a zip file. The first file in the archive happened to be UTF-16 instead of UFT-8 so a vanilla read_to_string for the file in the archive did not do the trick. I googled a bit and it seemed that, in order to be efficient, had to be done with unsafe code. Maybe I was very unlucky, but I was surprised that 5 minutes after trying rust for the very first time I had to use unsafe code.
Re:Why Rust closures are somewhat hard by steveklabnik on Tuesday September 11, 2018 @09:45AM (#17959615)
Re:Why Rust closures are somewhat hard by antaviana on Tuesday September 11, 2018 @10:36AM (#17960077)
I did not find a trivial way to go from the Vec<u8> returned by read_to_end to some kind of u16 container. Everything I found in Google involved unsafe code. Probably a function read_to_end returning a Vec<u16> would have been great.
Re:Why Rust closures are somewhat hard by steveklabnik on Tuesday September 11, 2018 @10:58AM (#17960297)
Ah yeah. It's tricky, but it also doesn't require unsafe: https://play.rust-lang.org/?gist=e261ed324a022ac82bb88adcee1...

I'm sure there's a package that makes this easy, but this took me about ten minutes to toss together from scratch.

Re:Why Rust closures are somewhat hard by drbawb on Tuesday September 11, 2018 @12:42PM (#17961301)
Agh! Chunks is what I was looking for! I was trying to whip up an example[1] and was positive I had used a pair-wise iterator before. The best I came up w/ was zipping two iterators of the hi/lo bytes. -- I feel the parent's pain, because this is coming from someone who has been programming Rust since it had green threads and `~ / @` pointers.

I love Rustdoc, but I really wish it wasn't so obtuse when it came to casually browsing the various iterator traits. Perhaps Steve, for the benefit of myself and thread parent, you could point us to some better-edited literature for the various iterator methods?

P.S: just wanted to add, if I were faced w/ this issue in production code, I likely would've just reached for the excellent byteorder[2] crate. It's so useful for "bit twiddling" like this.

[1]: https://play.rust-lang.org/?gist=4b4ff7263d9744caeb8bacd4c0d...

[2]: https://docs.rs/byteorder/1.2.6/byteorder/trait.ReadBytesExt...

Re:Why Rust closures are somewhat hard by steveklabnik on Tuesday September 11, 2018 @01:02PM (#17961449)
Ah yeah, byteorder would be the right call.

> Perhaps Steve, for the benefit of myself and thread parent, you could point us to some better-edited literature for the various iterator methods?

I used that page to find this. I knew it was "chunks" or "windows" or something, so I just looked at them (I guessed windows, but I was wrong).

Re:Why Rust closures are somewhat hard by antaviana on Tuesday September 11, 2018 @11:40AM (#17960702)
Ok, thanks I see. I suppose that it was a bit too much for a stackoverflow-prone noob like me, with only 5 minutes of rust flight time.
Re:Why Rust closures are somewhat hard by steveklabnik on Tuesday September 11, 2018 @11:43AM (#17960738)
Yeah, the big thing is how comfortable you are with bit twiddling. If you are, it's no big deal, but if you're not, it'd be much harder, for sure.
Re:Why Rust closures are somewhat hard by shawn on Monday September 10, 2018 @05:00PM (#17955146)
It is decidedly not a language to get things done. I say this as someone who put himself in the unfortunate position of challenging BurntSushi (author of ripgrep) to a coding duel, bragging that I could get LuaJIT to match his XSV performance (https://github.com/BurntSushi/xsv)

It took hours to figure out how to implement this in rust: https://github.com/sctb/lumen/blob/master/bin/lumen

If you want to see an "expert" programmer's attempt at making sense of the language, here you go: https://gist.github.com/shawwn/4d7a89188cac72f3e591f47c84d3c...

Now that it's done though, I see why people fall in love with Rust. It's really satisfying seeing Lumen's startup time drop from 200ms to 100ms.

But yes, like -- dude, at one point I just wanted to write a for loop like this, to grab some environment vars:

    let mut lumen_host = "luajit";
    let mut lua_path = "";
    let mut node_path = "";

    for (name, value) in env::vars() {
        if name == "LUMEN_HOST" {
            lumen_host = &value;
        } else if name == "LUA_PATH" {
            lua_path = &value;
        } else if name == "NODE_PATH" {
            node_path = &value;
        }
    }
    println!("{} {} {} {}", bin, lumen_host, lua_path, node_path);

Good luck with that! I'm sure there's a way to coax Rust into please-allow-me-to-just-compile-this, but the borrow checker is a cruel taskmaster. Whatever the syntax is, that's not it, and spending literally an hour trying to figure out how to store an environment variable into a separate variable doesn't feel very productive.

That said, Cargo is amazing. It's truly a wonderful, delightful piece of software. Cargo crates plus a dynamic language seems like a recipe for success.

Re:Why Rust closures are somewhat hard by steveklabnik on Monday September 10, 2018 @05:07PM (#17955216)
Is there a reason you looped through env::vars() rather than calling env::var on each key you wanted? That'd be much more straightforward:

  let lumen_host = env::var("LUMEN_HOST").unwrap_or(String::from("luajit"));
  let lua_path = env::var("LUA_PATH").unwrap_or(String::new());
  let node_path = env::var("NODE_PATH").unwrap_or(String::new());
Re:Why Rust closures are somewhat hard by pitaj on Monday September 10, 2018 @05:27PM (#17955359)
Yeah he's also using `if...else if` instead of a single `match`
Re:Why Rust closures are somewhat hard by shawn on Monday September 10, 2018 @06:56PM (#17955856)
Thanks! I appreciate pointing that out.
Re:Why Rust closures are somewhat hard by shawn on Monday September 10, 2018 @05:17PM (#17955290)
Thank you. I spent ... more time than I'm comfortable admitting trying to figure out how to do that.

Out of curiosity, did you spot any other antipatterns? I'm sure there are a bunch: https://gist.github.com/shawwn/4d7a89188cac72f3e591f47c84d3c...

I poo poo the language a lot, but it's satisfying to get the hang of it.

  fn realpath(path: &str) -> &str {
      unsafe {
          return CStr::from_ptr(
              libc::realpath(
                  path.as_ptr() as *const i8,
                  0 as *mut i8
                  )).to_str().unwrap();
      }
  }
Curious about that block in particular. I have no idea what I'm doing, so it'd be somewhat shocking if that were idiomatic.
Re:Why Rust closures are somewhat hard by steveklabnik on Monday September 10, 2018 @05:33PM (#17955405)
You're welcome! I have had a lot more time to familiarize myself with the standard library than you probably have.

That being said.. A lot of this stuff is things that already exist that you don't need to write yourself. dirname, basename, join, even s is .to_string. It's also the same as str. getenv is env().unwrap_or().

> Curious about that block in particular.

I would call https://doc.rust-lang.org/std/fs/fn.canonicalize.html and be done with it, instead of importing libc and going through all of this.

In the end, this should be like 40LOC, 50 tops, if you made use of the standard library rather than trying to re-implement it all :)

Re:Why Rust closures are somewhat hard by coldtea on Monday September 10, 2018 @05:28PM (#17955365)
>Thank you. I spent ... more time than I'm comfortable admitting trying to figure out how to do that.

The question is why. The relevant examples are everywhere:

https://doc.rust-lang.org/std/env/fn.var.html

https://doc.rust-lang.org/std/env/fn.vars.html

https://doc.rust-lang.org/book/second-edition/ch12-05-workin...

http://siciarz.net/24-days-rust-environment-variables/

Re:Why Rust closures are somewhat hard by shawn on Monday September 10, 2018 @05:40PM (#17955450)
FWIW, those four links are already purple for me.

The reason it's difficult is that it simultaneously introduces the concepts of optionals, unwrapping, string processing, variable assignment, and lifetime management. It's not like it's impossible to figure out. I was only saying the workload was similar to "baby's first vi session".

Re:Why Rust closures are somewhat hard by coldtea on Monday September 10, 2018 @05:43PM (#17955470)
That's understandable, but isn't it premature to judge Rust based on such a session?

That would be like criticizing vi based on "baby's first vi session", because "couldn't even exit the editor!".

Re:Why Rust closures are somewhat hard by shawn on Monday September 10, 2018 @05:50PM (#17955519)
I... am not sure. On one hand, it's instructive for language designers to know what turns out to be a barrier to entry. They're often unexpected things. And what's worse, users usually run into them and then quietly disappear; you almost never get the chance to see what trips newbies up in practice. It wasn't meant as a solid criticism, but more of a cathartic "yes, this language can be really counterintuitive at times." (Rust is in good company. It's the same reason Lisp is unpopular.)

On the other hand, you're absolutely right: the hypothesis is, given two equally-experienced programmers, one of them a Rust aficionado and the other a LuaJIT maniac, the LuaJIT dev will deliver reliable and maintainable software with an order of magnitude less effort. So you're right, that remains to be seen (to put it mildly).

Looking forward to seeing how close I can get to XSV's performance. It's a great benchmark.

Re:Why Rust closures are somewhat hard by pitaj on Monday September 10, 2018 @05:39PM (#17955445)
Does `canonicalize` [1] not work in place of `realpath`?

You have a couple of helper functions, like `s` and `str` which you might consider using `to_str` and `to_string` in their place, as it's more idiomatic to use them directly rather than save characters.

And obviously you can replace `getenv` with `env::var`.

1: https://doc.rust-lang.org/std/path/struct.Path.html#method.c...

Re:Why Rust closures are somewhat hard by shawn on Monday September 10, 2018 @06:58PM (#17955864)
Just wanted to say thanks for taking the time to give feedback. Swinging through the jungles of a new ecosystem is always fun, and guideposts like this are quite helpful.
Re:Why Rust closures are somewhat hard by withoutboats on Monday September 10, 2018 @05:07PM (#17955210)
The difference between &str and String is one of my least favorite parts of Rust, but I made your code compile with some pretty trivial changes: https://play.rust-lang.org/?gist=66789a8e86e3c2fd1803adc4bec...
Re:Why Rust closures are somewhat hard by imtringued on Wednesday September 12, 2018 @04:22AM (#17966484)
I have no rust experience but this looks like this would crash in C++ or C at runtime. You're taking a reference to a string that will be deleted in the next iteration or when the loop completes. You have to make a copy of the strings if you want to keep the code as is.
Re:Why Rust closures are somewhat hard by samnardoni on Monday September 10, 2018 @05:10PM (#17955241)
Why should Rust “just compile this” when it’s clearly bad code?
Re:Why Rust closures are somewhat hard by coldtea on Monday September 10, 2018 @05:24PM (#17955328)
It's not hard at all to get the above code to work, and I've only tried Rust for a couple of sub-1000-line weekend projects.
Re:Why Rust closures are somewhat hard by shawn on Monday September 10, 2018 @05:26PM (#17955353)
Well yes, if you've written 1000 lines of Rust, it's certainly trivial. Writing the first 20 lines is an <expletive> though.
Re:Why Rust closures are somewhat hard by coldtea on Monday September 10, 2018 @05:29PM (#17955375)
>Writing the first 20 lines is an <expletive> though.

Criticizing a language by how easy it is to write the "first 20 lines" doesn't sound really fare...

Re:Why Rust closures are somewhat hard by xfer on Monday September 10, 2018 @07:14PM (#17955927)
You don't think beginner's difficulty to use a language is worth criticizing considering a number of bike-shedding changes that are done to the language to make it easy for beginners?
Re:Why Rust closures are somewhat hard by leppr on Monday September 10, 2018 @05:08PM (#17955226)
For anyone new here, this is a copy pasta.