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 (_)/=\~/_(_) [email protected]
(_) /=\ ~/_ (_)
UazĂș (_) /=\ ~/_ (_) http://
in Peru (_) ____ /=\ ____ ~/_ ____ (_) uazu.net
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev