Graydon Hoare wrote: > To some extent. It depends a lot on the parsing task. I don't mean > to be dismissive. This is a great example. But I want to clarify > things: > > - In a Serious Parser, errors are managed explicitly because error > reporting to the user is an Important Diagnostic Feature of the > parsing. There's a whole error formatting, diagnostic emitting, > suppressing-and-counting logic built in that goes beyond what an > exception will do. You are always going to be doing manual work > All Through The Parser. > > - In a Throwaway Parser, it's not clear to me that treating all > failures as interchangeable, as with tasks ("we can't get > meaningful input") is losing a lot of fidelity over an > exception-based approach. That's what failure is for in rust.
Okay, that makes sense. The coder just needs to get used to using tasks for containment instead of other constructions. As I code from now on (in other languages) I will try to imagine how I would structure the same thing in Rust based on your two options (pre-specify a solution, or fail the task). > [...] > > Sorry to blather on like this, but ... the point of "lightweight > tasks" in this language is that they're lightweight, and get used > early and often. If everyone's reaction to "use a task" is "oh > bother, those are far too heavy", I think we've made a mistake > somewhere. > > >(Tasks are again taking a role like a language construct, not merely > >as a scheduling entity.) > > They originally were first class, and I am guilty-as-charged with > being willing to treat them as relatively high-ranking concepts in > the design. The design thesis in rust is that proper structured > programming *needs* task-like memory-and-concurrency partitioning to > scale robustly, and it's one of the things we've been falling down > on all through the 80s, 90s, 2000s. Languages keep making devices > that don't quite get used, systems wind up with far too few internal > boundaries, so are far too serial and fragile. Sorry -- I didn't mean for it to sound like criticism. In a previous thread I was trying to establish whether Rust's tasks were first-class language constructs and optimisable, or just scheduling entities. I agree. I really do like the whole first-class "task as a construct" approach -- with task primitives in the same list as if/while/for. However, I still worry that you may need to apply "identity transformations" on task use to make them sufficiently efficient, when Rust approaches C's efficiency in all other aspects. By "identity transformations" I mean something like algebraic identities, for example, converting a certain pattern of task+port use into another one, or into an inlined (serial) version, where the effect is indistinguishable to the programmer, but lets Rust run it faster. (There were some scenarios in a previous thread.) The question is where will Rust's eventual task-costs lie on the scale: totally free (optimised down to what I might hand-code if I knew the number of cores I was running on), cheap-enough (probably I shouldn't use too many hundred, and tasks will slow me down in inner loops), or too-slow (avoid tasks!). I would prefer "totally free" if possible -- when Rust eventually gets to that level of optimisation -- which means that the coder can use them freely as a language construct like braces or inline functions or something, without any concern at all that they might cause inefficiency. Jim -- Jim Peters (_)/=\~/_(_) j...@uazu.net (_) /=\ ~/_ (_) UazĂș (_) /=\ ~/_ (_) http:// in Peru (_) ____ /=\ ____ ~/_ ____ (_) uazu.net _______________________________________________ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev