Re: [rust-dev] Back to errors, failures and exceptions

2012-06-05 Thread Niko Matsakis

On 6/4/12 4:56 AM, David Rajchenbach-Teller wrote:

I actually meant the functions called by the implementation of `remove`.
For instance, `copy` generally does not have to return anything
meaningful.


I see.  However, I'm not sure I agree.  I think `copy` ought to return 
something that indicates whether it succeeded and---if not---why not.



This would raise a red flag during code review, just as `try { remove();
} catch (Exception e) {}` ought to raise a red flag.

Do I understand correctly that you mean actual reviews and not
lint-style warnings?


Yes.  I meant that the compiler would flag an error for ignored return 
values.  If the programmer insisted on ignoring the return value, it's 
suggests that a comment is warranted explaining why.



Niko
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Back to errors, failures and exceptions

2012-06-04 Thread David Rajchenbach-Teller
On 6/2/12 6:06 PM, Niko Matsakis wrote:
 On 6/1/12 2:59 AM, David Rajchenbach-Teller wrote:
 The other problem is that the function may not have enough information
 to determine what is locally unrecoverable. I believe that `remove` is
 a good example of issues whose recoverability depend on the context.
 
 I'm not sure I understand what the problem is.  It seems like it is easy
 for `remove()` to recover and return a `result` type.  The caller can
 then elect to handle the error however it chooses.

I actually meant the functions called by the implementation of `remove`.
For instance, `copy` generally does not have to return anything
meaningful. So if we assume that it is locally recoverable, in this
design, it should return a `result` type – but chances are that users
will forget to pattern-match it, since they do not care about that
result. If we assume that it is generally irrecoverable, well, we have
to use a failure as an exception in the implementation of `remove`.


 A couple of potential problems I can see:
 
 - if this is a recurse `remove()`, it may be possible to continue and
 delete other files.  This would seem like a good candidate for a
 Graydon-style handler, so that `remove()` could invoke the handler with
 the details of which file it failed to remove and why and the handler
 can indicate whether `remove()` ought to continue.
 
 - the caller can easily ignore the return value accidentally and thus
 not be aware that return has failed.  We probably ought to make it so
 that ignored return values must be explicitly acknowledged, as in
 O'caml, using the lint pass. I think this will prevent a lot of bugs in
 general.  Therefore, to call `remove()` without caring whether it
 succeeds or fails you would write:
 
 let _ = remove(...);

Good point, I had not thought about that.

 This would raise a red flag during code review, just as `try { remove();
 } catch (Exception e) {}` ought to raise a red flag.

Do I understand correctly that you mean actual reviews and not
lint-style warnings?

Cheers,
 David

-- 
David Rajchenbach-Teller, PhD
 Performance Team, Mozilla



signature.asc
Description: OpenPGP digital signature
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Back to errors, failures and exceptions

2012-06-04 Thread Graydon Hoare

On 12-06-01 5:47 AM, David Rajchenbach-Teller wrote:


My main concern is that we would end up with a Rust used in-the-wild
without either guidelines, library or mechanism for handling non-fatal
issues.


Yeah. We'll have to pin down a technique and use it widely through the 
stdlib when we're comfortable with it. Similar to the matter of classes 
/ objects / ifaces. We're still doing some late-stage design work here. 
Shouldn't be much longer, a few months and we'll have to pick something 
and commit to it.



I will keep using issue for the moment instead of
error/exception/failure/... to avoid projecting too much semantics.


Ok.


* Function `handler::try` prepares for execution a block (let's call it
the action block) and lets the developer registers closures to handle
various issue cases that may arise during the execution of that action
block.


Yes. Might not be necessary to write in this form, but it scopes the 
push/pop of new handlers. This was just a sketch and I'm sure there are 
some conceptual / implementation bugs we'd need to iron out to make it 
just right.



* Function `?.handle(some_issue)` registers a block to handle one
specific kind of issue.


Yes.


* Execution of the handler block takes place locally, without any stack
unwinding.


Yes.


* Execution of the action block starts at the end of the chain of
`?.handle(...)`. Is there a way to do this in Rust or does this require
the addition of some kind of terminator?


Not sure I understand. The handler that gets run is the head of a list 
held in a task-local variable indexed by the constant in question (a 
hack: every constant has a unique address in the process, so is 
effectively a key you can use as per-process global unique value). 
Different constants refer to different handler lists, hence have no 
relationship. The .handle(...){...}.handle(...){...} chain is just 
pushing new entries on multiple handler lists simultaneously so they all 
get popped off at the same time when the try{...} block completes.



* A call to `signal` gives a chance to other issue handlers to execute.
Do I understand correctly that this actually somehow pops the issue
handler to avoid cycles?


It'll have to do so, yes.


* I also have the impression that a call to `signal` also performs some
form of non-local return. Am I right?


No. It just picks the head of the handler list, call that H, then shifts 
the task-local handler list down by one so H can call outer handlers, 
then invokes H.



By the way, if I understand correctly, I believe that type name
`handler...` is a little counter-intuitive.


Ok. Other suggestions welcome.


I will reply once I am sure that I understand the example :)


Please do follow up with further questions. If you want to drop by IRC 
and do some interactive QA that's also likely to help. I want to make 
sure we develop something here that at least *conceptually* sits well 
with everyone; it's a larger question whether it feels good in practice.


-Graydon
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Back to errors, failures and exceptions

2012-06-02 Thread Niko Matsakis

On 6/1/12 2:59 AM, David Rajchenbach-Teller wrote:

The other problem is that the function may not have enough information
to determine what is locally unrecoverable. I believe that `remove` is
a good example of issues whose recoverability depend on the context.


I'm not sure I understand what the problem is.  It seems like it is easy 
for `remove()` to recover and return a `result` type.  The caller can 
then elect to handle the error however it chooses.


A couple of potential problems I can see:

- if this is a recurse `remove()`, it may be possible to continue and 
delete other files.  This would seem like a good candidate for a 
Graydon-style handler, so that `remove()` could invoke the handler with 
the details of which file it failed to remove and why and the handler 
can indicate whether `remove()` ought to continue.


- the caller can easily ignore the return value accidentally and thus 
not be aware that return has failed.  We probably ought to make it so 
that ignored return values must be explicitly acknowledged, as in 
O'caml, using the lint pass. I think this will prevent a lot of bugs in 
general.  Therefore, to call `remove()` without caring whether it 
succeeds or fails you would write:


let _ = remove(...);

This would raise a red flag during code review, just as `try { remove(); 
} catch (Exception e) {}` ought to raise a red flag.


Are there other complications I have not considered?


Niko
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Back to errors, failures and exceptions

2012-06-01 Thread David Rajchenbach-Teller
On 5/29/12 4:57 PM, Niko Matsakis wrote:
 This code seems wrong... what if an error occurs as part of the call to
 `copy()`, for example?

The idea is to simply propagate errors that take place as part of
`copy`, in a ML/C++/Java/Haskell manner.

[...]

 In general it seems there are three classes of errors

 - globally unrecoverable (just call `fail`)
 - locally unrecoverable (return a `resultX,Y` type)
 - recoverable (pass in handler or error reporter)

 Globally unrecoverable means that the whole task cannot continue (this
 is clearly not appropriate for libraries). Locally recoverable means
 that some subset of the program must abort, but some outer handler could
 possibly catch it.  Recoverable means that it's the sort of error where
 the procedure could carry on, but the caller may still want to know
 about it.  These two are suitable for general purpose libraries,
 depending on the case.  We certainly use all three in the compiler,
 though primarily the first and the third.

 This whole scheme isn't terribly composable, though.  Code must be
 written differently depending on whether it may abort due to errors and
 so forth.  This is precisely what exceptions were aiming to solve, I
 suppose (Java's checked exceptions representing a kind of middle
 ground).  It may be that error propagation is too important to be
 papered over entirely, though.

Indeed, I suspect that achieving composability without sacrificing
safety or performance is the big issue here.

The other problem is that the function may not have enough information
to determine what is locally unrecoverable. I believe that `remove` is
a good example of issues whose recoverability depend on the context.

Cheers,
 David

-- 
David Rajchenbach-Teller, PhD
 Performance Team, Mozilla



signature.asc
Description: OpenPGP digital signature
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Back to errors, failures and exceptions

2012-06-01 Thread David Rajchenbach-Teller
On 5/29/12 5:52 PM, Benjamin Striegel wrote:
 * The system _must_ not prevent, some day, developers from calling Rust
 from JavaScript.
 * The system _must_ not prevent, some day, developers from calling
 JavaScript from Rust.
 
 I'm not aware of any precedents for calling out of or into Javascript,
 in any language. What specific constraints does this impose?

Well, in Firefox, we have been calling out of/into JS for ages, first
with XPConnect and now with js-ctypes. Neither is fully satisfactory,
but they are both useful.

XPConnect connects the C++ subset used at Mozilla (in particular, C++
witout exceptions) and JavaScript (and possibly other languages). Calls
can only be placed through well-defined interfaces. JavaScript
exceptions are converted to C++ error return value, with two rules:
- throwing an integer from JavaScript passes that integer to C++;
- throwing any other value from JavaScript converts it to a default
error value.
Conversely, returning an error value from C++ is converted to throwing
the corresponding integer in JS.

js-ctypes connects C to JavaScript. As C has no exceptions, this
simplifies things (although decoding 64-bit C return values in JS is a
bit messy). I do not know the semantics of throwing an exception from JS
to C, but I suspect this is messy.

Now, in Rust, I do not know exactly how to best do this, but I suspect
that we would want calls to JavaScript to return a sum type result/error.

Cheers,
 David
-- 
David Rajchenbach-Teller, PhD
 Performance Team, Mozilla



signature.asc
Description: OpenPGP digital signature
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Back to errors, failures and exceptions

2012-06-01 Thread David Rajchenbach-Teller
On 5/30/12 5:35 AM, Joe Groff wrote:
 On Tue, May 29, 2012 at 7:57 AM, Niko Matsakis n...@alum.mit.edu wrote:
 In general it seems there are three classes of errors

- globally unrecoverable (just call `fail`)
- locally unrecoverable (return a `resultX,Y` type)
- recoverable (pass in handler or error reporter)
 
 If you have closures with nonlocal returns, callback handlers could
 work in both the locally unrecoverable and recoverable cases.

It is my understanding that we really do not want closures with nonlocal
returns, as they cause the exact same kind of implementation issues as
exceptions, in terms of both performance, semantics and typing (at least
if they are not almost-local returns).

Cheers,
 David


-- 
David Rajchenbach-Teller, PhD
 Performance Team, Mozilla



signature.asc
Description: OpenPGP digital signature
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Back to errors, failures and exceptions

2012-06-01 Thread David Rajchenbach-Teller
On 5/30/12 3:41 AM, Graydon Hoare wrote:
 Hi!
 
 Sorry I've been away, I wanted to talk about this issue, or, well, kinda
 just remind you and others in this conversation that there is (in my
 mind at least, and in the bug tracker[1]) a plan for how to do this.
 I've been continuing to assume this is something we'd handle with
 per-task dynamic-scoped values, just haven't got around to implementing
 them yet. Should be almost entirely library code.

Ah, great!
My main concern is that we would end up with a Rust used in-the-wild
without either guidelines, library or mechanism for handling non-fatal
issues.

 Here's a sketch of your 'move' function written in this style:
 
 https://gist.github.com/1f9c8fe1debd9a504eef

Let me rephrase your code to be sure that I understand it correctly.

I will keep using issue for the moment instead of
error/exception/failure/... to avoid projecting too much semantics.

* Function `handler::try` prepares for execution a block (let's call it
the action block) and lets the developer registers closures to handle
various issue cases that may arise during the execution of that action
block.

* Function `?.handle(some_issue)` registers a block to handle one
specific kind of issue.

* Execution of the handler block takes place locally, without any stack
unwinding.

* Execution of the action block starts at the end of the chain of
`?.handle(...)`. Is there a way to do this in Rust or does this require
the addition of some kind of terminator?

* A call to `signal` gives a chance to other issue handlers to execute.
Do I understand correctly that this actually somehow pops the issue
handler to avoid cycles?

* I also have the impression that a call to `signal` also performs some
form of non-local return. Am I right?

By the way, if I understand correctly, I believe that type name
`handler...` is a little counter-intuitive.


 
 I think a sufficiently gnarly implementation that's allowed to hang a
 special-variable list off the side of each task should be able to work
 given that, just keying off the different addresses of the various
 consts in memory. A bit of a hack but I think it might work.
 
 Note as discussed earlier, in that example the handling all happens _at_
 the dynamic site of signalling (via a call to a passed-down closure,
 accessed through the handler library) not by unwinding. Unwinding still
 only happens on failure and is still idempotent, unrecoverable.
 
 Does this not sit well with you currently?

I will reply once I am sure that I understand the example :)

Cheers,
 David


-- 
David Rajchenbach-Teller, PhD
 Performance Team, Mozilla



signature.asc
Description: OpenPGP digital signature
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Back to errors, failures and exceptions

2012-05-29 Thread David Rajchenbach-Teller
As promised, I have attempted to rewrite my original function |move|
with a mechanism that would let us define issue-handling policies. This
mechanism is inspired by both the current thread and the previous thread
on exceptions, a few months ago.

So far, the result is not too convincing yet, but it can certainly serve
as a base for improvements: https://gist.github.com/2823196



signature.asc
Description: OpenPGP digital signature
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Back to errors, failures and exceptions

2012-05-29 Thread Niko Matsakis
This code seems wrong... what if an error occurs as part of the call to 
`copy()`, for example?


As a kind of experience report, I have been using `result` types for 
those parts of the compiler where errors must be recoverable rather than 
just being reported to the user and papered over.  I have found it's 
pretty nice except that writing


first_thing().chain { |res1|
second_thing().chain { |res2|
ok(infallible_combination_of(res1, res2))
}
}

gets a little old and induces horrible rightward drift.  A macro along 
the lines of Haskell's do notation would address this:


#do {
let res1 = first_thing();
let res2 = second_thing();
infallible_combination_of(res1, res2)
}

In general it seems there are three classes of errors

- globally unrecoverable (just call `fail`)
- locally unrecoverable (return a `resultX,Y` type)
- recoverable (pass in handler or error reporter)

Globally unrecoverable means that the whole task cannot continue (this 
is clearly not appropriate for libraries). Locally recoverable means 
that some subset of the program must abort, but some outer handler could 
possibly catch it.  Recoverable means that it's the sort of error where 
the procedure could carry on, but the caller may still want to know 
about it.  These two are suitable for general purpose libraries, 
depending on the case.  We certainly use all three in the compiler, 
though primarily the first and the third.


This whole scheme isn't terribly composable, though.  Code must be 
written differently depending on whether it may abort due to errors and 
so forth.  This is precisely what exceptions were aiming to solve, I 
suppose (Java's checked exceptions representing a kind of middle 
ground).  It may be that error propagation is too important to be 
papered over entirely, though.



Niko

 On 5/29/12 1:07 AM, David Rajchenbach-Teller wrote:

As promised, I have attempted to rewrite my original function |move|
with a mechanism that would let us define issue-handling policies. This
mechanism is inspired by both the current thread and the previous thread
on exceptions, a few months ago.

So far, the result is not too convincing yet, but it can certainly serve
as a base for improvements: https://gist.github.com/2823196



___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Back to errors, failures and exceptions

2012-05-29 Thread Benjamin Striegel
 * The system _must_ not prevent, some day, developers from calling Rust
 from JavaScript.
 * The system _must_ not prevent, some day, developers from calling
 JavaScript from Rust.

I'm not aware of any precedents for calling out of or into Javascript, in
any language. What specific constraints does this impose?

On Wed, May 23, 2012 at 8:47 AM, David Rajchenbach-Teller 
dtel...@mozilla.com wrote:

 Actually, one of the conclusions of our previous discussion is that
 Java/C++/ML-style exceptions are probably not what we want for Rust. I
 seem to remember that we also concluded that using failures as
 exceptions was probably not the right course.

 Hence this new thread :)

 Let me put together what I believe are a few desirable qualities of an
 issue management system. For the moment, let's not wonder whether that
 system is a language feature, a library or a coding guideline.

 * The system _must_ not prevent developers from calling C code from Rust.
 * The system _must_ not prevent developers from passing a pointer to a
 Rust function to C code that will call back to it.
 * The system _must_ not prevent, some day, developers from calling Rust
 from JavaScript.
 * The system _must_ not prevent, some day, developers from calling
 JavaScript from Rust.
 * Issues _must_ not be restricted to integers (or to one single type).
 * The default behavior in case of untreated issue _should_ be to
 gracefully kill the task or the application.
 * Whenever an untreated issue kills a task/application, it _should_
 produces a report usable by the developer for fixing the issue.
 * It _should_ be possible to deactivate that killing behavior. There
 _may_ be limitations.
 * It _should_ be possible to deactivate that killing behavior
 conditionally (i.e. only for some errors).
 * The system _should_ eventually have a low runtime cost – in
 particular, the case in which no killing happens should be very fast.


 Do we agree on this base?

 Cheers,
  David

 On 5/22/12 4:56 AM, Bennie Kloosteman wrote:
  Are exceptions a good model for systems programming ?
 
  - legacy C programs cant call you without a wrapper which translates
  all possible exceptions
  - unwinding a stack is probably not a good idea in a kernel or when
  you transition into protected/user mode.( I know of very few kernels
  that use exceptions ).
  - Its not just legacy , Winrt uses C++ classes but returns error codes
  tor low level APIs.
 
  However its very nice for user programs . These days these different
  worlds works quite well , c libs which Is mainly used for system
  programming don't use them  and C++ apps are more user programs and
  they do  , C++ calls C , C rarely calls C++. Obviously if you write a
  kernel or shared library  you cannot use exceptions if  c programs
  call your code and there is a lot of c out there While not really
  an issue for the language ( just dont use exceptions) it means a
  standard lib that throws an exception would be a pain for such work
  and you would need a different standard lib , which is an issue .
 
  BTW could Rust use tasks as a substitute for exception scopes ? Tasks
  have error bubbling , hiding  , stack unwinding  , throw ( fail) and
  should have integrated logging . You could put a sugar syntax around
  it but it would still work when being called by c.  Also with tasks
  you can cancel or do timeouts giving asynronous exceptions  which are
  really needed ( eg in most systems cancel a long running task is very
  anoying very long pause). and which most trivial exception
  implementations don't do ..Not sure if this is the right way but there
  seems a lot of overlap and it would work with C and systems
  programming,.
 
  Ben
  ___
  Rust-dev mailing list
  Rust-dev@mozilla.org
  https://mail.mozilla.org/listinfo/rust-dev


 --
 David Rajchenbach-Teller, PhD
  Performance Team, Mozilla


 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev


___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Back to errors, failures and exceptions

2012-05-29 Thread Joe Groff
On Tue, May 29, 2012 at 7:57 AM, Niko Matsakis n...@alum.mit.edu wrote:
 In general it seems there are three classes of errors

    - globally unrecoverable (just call `fail`)
    - locally unrecoverable (return a `resultX,Y` type)
    - recoverable (pass in handler or error reporter)

If you have closures with nonlocal returns, callback handlers could
work in both the locally unrecoverable and recoverable cases. Instead
of returning a resultX,Y type, the function could return the result
of calling its handler, with the handler having the ability to jump
out if a result value doesn't make sense. If a function can't handle a
condition locally and wants to pass it upwards, it can take a callback
of its own and call it for those cases, and that callback in turn
could jump out into its own scope if necessary.

---
fn foo(on_error) {
let res1 = first_thing() {|| goto local_handler; }; // handle
unrecoverable condition locally
let res2 = second_thing() {|| on_error() }; // pass the buck
let res3 = third_thing() {|| alternative_third_thing() }; //
handle recoverable condition

ret combination_of(res1, res2, res3);

local_handler:
ret alternate_thing();
}
---

A somewhat more nuts-and-bolts implementation of exceptions, I guess.
I know arbitrary NLRs in closures can't be handled generally without
affecting performance and that break/cont in for loops are handled
specially, so maybe that rules this approach out.

-Joe
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Back to errors, failures and exceptions

2012-05-25 Thread Kevin Cantu
This conversation reminds me of Alexandrescu's talk about D's scope keyword:
http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012/Three-Unlikely-Successful-Features-of-D

It looks like a graceful syntax for handling all sorts of nested error and
failure cleanup...
On May 25, 2012 3:00 AM, Bennie Kloosteman bkloo...@gmail.com wrote:

 On Thu, May 24, 2012 at 9:16 PM, David Rajchenbach-Teller
 dtel...@mozilla.com wrote:
  On 5/24/12 12:40 PM, Bennie Kloosteman wrote:
  * The system _must_ not prevent developers from calling C code from
 Rust.
  * The system _must_ not prevent developers from passing a pointer to a
  Rust function to C code that will call back to it.
  * The system _must_ not prevent, some day, developers from calling Rust
  from JavaScript.
  * The system _must_ not prevent, some day, developers from calling
  JavaScript from Rust.
 
  These should be unsafe - I believe this is the case with rust.
 
  I am not sure if you mean this in relation with all four points or with
  the last one. So, indeed, I see no reason to change the fact that calls
  to C are considered unsafe.
 
  For calls to JavaScript, I have not given it much thought. I suppose
  that they could be either unsafe or somehow managed.

 externals calls either must work 100% ( including type conversions) or
 be marked unsafe... if it breaks type or memory safety you need to say
 that.

 Speaking of which we can handle C errors in calls but what about C++
 exceptions ? Does any C++ code we hook need exception wrappers ?
 Also any error system rust should work when called from C  ( unlike
 C++ exceptions) .


 
  * Issues _must_ not be restricted to integers (or to one single type).
 
  Yes  but returning error codes and then looking up further issue
  detail separately is quite useful since your passing around little
  information it gives the highest chance in a partially unsafe
  environment of working out what happened . eg if the stack is
  corrupted or you have major issues its useful that the error is memory
  logged  ( eg in ring 0 in a  rust based kernel ) and then retrieved .
  A simple  integer return value has a much better chance..
 
  Interesting point.
  Are we talking about implementing Servo with a ring-like mechanism?
 
  If so, I suspect that we may simply not want this kind of issues to
  cross ring boundaries. Otherwise, if we let high-level issues cross
  boundaries, we could be sending closures, for instance, which sounds
  like a bad idea.
 
  For the moment, I believe that we should assume that the issue mechanism
  will not be used for crossing ring boundaries.

 Is rust or this error handling solely for Servo ? What about writing
 say a kernel or Linux kernel modules in rust ? To me system
 programming is where Rust should be. If its all working that's fine
 but  I was showing some horrible worst cases and its still nice to get
 some error information rather than a horrible crash .

 A similar thing can occur with any external call to C or asm. But the
 concept is the same try to get at least an error code returned even if
 the most abysmal circumstances.

 
  This could be a 64 bit  value with the low 32 bits the error and the
  upper 32 bit some sort of hash code.
 
  A more detailed but not guaranteed representation should be a detailed
  structure. with time stamps etc  I would even say this detail should
  be created asynchronously via a new task while the actual error is
  returned immediately .
 
  errno is a pain ,  but not because it returns an int but because all
  the information you can retrieve on it is a error string.
 
  Actually you could log all the detail and just reference an index to
  the log , Though this would require recent log entries to be
  recallable and have more detail in the log fields eg error category
  and level  ( which are useful in a log anyway)
 
  All these are interesting points, although perhaps they arrive a little
  too early in the thread :)
 

 Im not so young anymore so when I train of thoughts I like to get it
 on E-paper ;-)

  * The default behavior in case of untreated issue _should_ be to
  gracefully kill the task or the application.
 
  If its integrated with tracing and logging the default behaviour
  depends on the error type
 
  eg Trace  , Log, Warning or Error continue , Critical  = halt.
 
  A tracer/logger with this kind of semantics could certainly be built on
  top of the issue mechanism. I tend to believe that that they should be
  integrated from the start, though.

 Agree,
 
  * Whenever an untreated issue kills a task/application, it _should_
  produces a report usable by the developer for fixing the issue.
  * It _should_ be possible to deactivate that killing behavior. There
  _may_ be limitations.
  * It _should_ be possible to deactivate that killing behavior
  conditionally (i.e. only for some errors).
 
  also a task can monitor child tasks for errors ( I don't think Rust
  has events but something like that) and choose on 

Re: [rust-dev] Back to errors, failures and exceptions

2012-05-25 Thread David Rajchenbach-Teller
On 5/25/12 5:43 PM, Kevin Cantu wrote:
 This conversation reminds me of Alexandrescu's talk about D's scope keyword:
 http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012/Three-Unlikely-Successful-Features-of-D
 
 It looks like a graceful syntax for handling all sorts of nested error
 and failure cleanup...

Do you know if there is a paper version of this talk?

Cheers,
 David

-- 
David Rajchenbach-Teller, PhD
 Performance Team, Mozilla



signature.asc
Description: OpenPGP digital signature
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Back to errors, failures and exceptions

2012-05-25 Thread Matthieu Monrocq
On Fri, May 25, 2012 at 7:16 PM, David Rajchenbach-Teller 
dtel...@mozilla.com wrote:

 On Fri May 25 18:01:25 2012, Patrick Walton wrote:
  On 05/25/2012 08:43 AM, Kevin Cantu wrote:
  This conversation reminds me of Alexandrescu's talk about D's scope
  keyword:
 
 http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012/Three-Unlikely-Successful-Features-of-D
 
 
  It looks like a graceful syntax for handling all sorts of nested error
  and failure cleanup...
 
  I like the scope keyword, FWIW. It'd be even better if you didn't have
  to provide a variable name if all you want to do is execute some code
  at the end of the block.
 
  This would provide a facility like Go's defer keyword, but more
  general since it also admits C++ RAII patterns.
 
  Patrick

 What's the difference between |scope| and Rust's resources, exactly?

 Cheers,
  David

 --
 David Rajchenbach-Teller, PhD
  Performance Team, Mozilla


 Regarding adding logs to the errors:

- Boost.Exception has something similar: you can add class instances to the
exception using the error info mechanism [1]
- It also reminds me of what happens in case of failures using the note
expressions, I believe the same notes could be reused in case of
exceptions/errors to provide additional logs.

Of course, there is a difference between the two schemes. Boost's is
somewhat more powerful because it does not consist of adding simple strings
but full-blown objects (which could be conditionned to be printable), and
thus allow inspection of structured data at the error-handling site. It may
be thought of as overkill too...


Regarding D's scope keyword [2]

There are several statements based on it:

 - scope(exit)  where  is executed on exit, no matter what
 - scope(failure)  where  is executed on exit if the previous
statement failed
 - scope(success)  where  is executed on exit if the previous
statement succeeded

On the other hand, it kind of look like a hack, maybe it is an issue of
getting used to it though.


 [1]:
http://www.boost.org/doc/libs/1_49_0/libs/exception/doc/error_info.html
 [2]: http://dlang.org/exception-safe.html
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Back to errors, failures and exceptions

2012-05-25 Thread Patrick Walton

On 5/25/12 10:16 AM, David Rajchenbach-Teller wrote:

What's the difference between |scope| and Rust's resources, exactly?


scope would be executed unconditionally at the end of the current 
block, while the rules for standard Rust RAII are somewhat more complex 
and depend on the initedness of the variable, whether it was moved, etc. 
There's a hidden dynamic flag created by the compiler and set


I've been toying with the idea of changing standard Rust RAII to 
execute this when the variable goes dead (in the classic compiler 
liveness sense) and introduce a scope keyword for something more like 
C++ or D RAII in which the liveness of the variable is restricted to be 
exactly the extent of the block, making it safe to unconditionally run 
the destructor once the variable goes out of scope.


Patrick
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Back to errors, failures and exceptions

2012-05-25 Thread Patrick Walton

On 5/25/12 10:28 AM, Patrick Walton wrote:

There's a hidden dynamic flag created by the compiler


Hit send too early. There's a hidden dynamic flag created by the 
compiler to track initedness for each variable.


Patrick
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Back to errors, failures and exceptions

2012-05-25 Thread Niko Matsakis

On 5/25/12 10:28 AM, Patrick Walton wrote:
I've been toying with the idea of changing standard Rust RAII to 
execute this when the variable goes dead (in the classic compiler 
liveness sense) and introduce a scope keyword for something more 
like C++ or D RAII in which the liveness of the variable is restricted 
to be exactly the extent of the block, making it safe to 
unconditionally run the destructor once the variable goes out of scope.


It seems like the official rule could be as simple as the destructor is 
executed at some point after the last access and before the exit from 
the scope.  This would give us more freedom.


I don't know the details of the D version, but I like the idea of scope 
as it makes it more explicit when you are creating a resource just for 
side-effects.  It also avoids the need for unused variables.  For 
example, this code that is sprinkled throughout trans:


let _icx = cx.insn_ctxt(trans_local_var);

would become something like:

scope cx.insn_ctxt(trans_local_var);

which seems much clearer to me.


Niko
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Back to errors, failures and exceptions

2012-05-25 Thread Brian Anderson

On 05/25/2012 03:00 AM, Bennie Kloosteman wrote:

On Thu, May 24, 2012 at 9:16 PM, David Rajchenbach-Teller
dtel...@mozilla.com  wrote:

On 5/24/12 12:40 PM, Bennie Kloosteman wrote:

* The system _must_ not prevent developers from calling C code from Rust.
* The system _must_ not prevent developers from passing a pointer to a
Rust function to C code that will call back to it.
* The system _must_ not prevent, some day, developers from calling Rust
from JavaScript.
* The system _must_ not prevent, some day, developers from calling
JavaScript from Rust.


These should be unsafe - I believe this is the case with rust.


I am not sure if you mean this in relation with all four points or with
the last one. So, indeed, I see no reason to change the fact that calls
to C are considered unsafe.

For calls to JavaScript, I have not given it much thought. I suppose
that they could be either unsafe or somehow managed.


externals calls either must work 100% ( including type conversions) or
be marked unsafe... if it breaks type or memory safety you need to say
that.

Speaking of which we can handle C errors in calls but what about C++
exceptions ? Does any C++ code we hook need exception wrappers ?
Also any error system rust should work when called from C  ( unlike
C++ exceptions) .


The current situation is that C++ code must not throw into Rust code or 
the runtime will abort and Rust code that has been called from native 
code must not fail or the runtime will abort. We can probably come up 
with some way to handle both these.


-Brian
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Back to errors, failures and exceptions

2012-05-25 Thread Bennie Kloosteman
I thought Rust was not going to implement C++  style exceptions .  are
these scopes not very similar ?  Do you unwind the stack etc  when you
are nested deeply within a scope and a fail occurs ?

Also more importantly can you safely handle tasks that were created in
the now to be unwound scopes ?  I don't know about the internals of
Rust Tasks but yanking the stack when a sub task was created from it
and is running on another thread could get tricky.

This was the main reason I was thinking scopes should be a task
underneath  while its heavy it would not be used in most cases. In
most case use a Com Hresult/ IErrorInfo scheme ( which can hook into
logging)  , when you do need guaranteed unwinding  use a scope ( or
fail scope) based on a task behind the scenes. To me it fits nicely
into the ideas of the language.



Ben

 scope would be executed unconditionally at the end of the current block,
 while the rules for standard Rust RAII are somewhat more complex and depend
 on the initedness of the variable, whether it was moved, etc. There's a
 hidden dynamic flag created by the compiler and set

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Back to errors, failures and exceptions

2012-05-24 Thread David Rajchenbach-Teller
On 5/24/12 12:40 PM, Bennie Kloosteman wrote:
 * The system _must_ not prevent developers from calling C code from Rust.
 * The system _must_ not prevent developers from passing a pointer to a
 Rust function to C code that will call back to it.
 * The system _must_ not prevent, some day, developers from calling Rust
 from JavaScript.
 * The system _must_ not prevent, some day, developers from calling
 JavaScript from Rust.

 These should be unsafe - I believe this is the case with rust.

I am not sure if you mean this in relation with all four points or with
the last one. So, indeed, I see no reason to change the fact that calls
to C are considered unsafe.

For calls to JavaScript, I have not given it much thought. I suppose
that they could be either unsafe or somehow managed.

 * Issues _must_ not be restricted to integers (or to one single type).

 Yes  but returning error codes and then looking up further issue
 detail separately is quite useful since your passing around little
 information it gives the highest chance in a partially unsafe
 environment of working out what happened . eg if the stack is
 corrupted or you have major issues its useful that the error is memory
 logged  ( eg in ring 0 in a  rust based kernel ) and then retrieved .
 A simple  integer return value has a much better chance..

Interesting point.
Are we talking about implementing Servo with a ring-like mechanism?

If so, I suspect that we may simply not want this kind of issues to
cross ring boundaries. Otherwise, if we let high-level issues cross
boundaries, we could be sending closures, for instance, which sounds
like a bad idea.

For the moment, I believe that we should assume that the issue mechanism
will not be used for crossing ring boundaries.

 This could be a 64 bit  value with the low 32 bits the error and the
 upper 32 bit some sort of hash code.

 A more detailed but not guaranteed representation should be a detailed
 structure. with time stamps etc  I would even say this detail should
 be created asynchronously via a new task while the actual error is
 returned immediately .

 errno is a pain ,  but not because it returns an int but because all
 the information you can retrieve on it is a error string.

 Actually you could log all the detail and just reference an index to
 the log , Though this would require recent log entries to be
 recallable and have more detail in the log fields eg error category
 and level  ( which are useful in a log anyway)

All these are interesting points, although perhaps they arrive a little
too early in the thread :)

 * The default behavior in case of untreated issue _should_ be to
 gracefully kill the task or the application.

 If its integrated with tracing and logging the default behaviour
 depends on the error type

 eg Trace  , Log, Warning or Error continue , Critical  = halt.

A tracer/logger with this kind of semantics could certainly be built on
top of the issue mechanism. I tend to believe that that they should be
integrated from the start, though.

 * Whenever an untreated issue kills a task/application, it _should_
 produces a report usable by the developer for fixing the issue.
 * It _should_ be possible to deactivate that killing behavior. There
 _may_ be limitations.
 * It _should_ be possible to deactivate that killing behavior
 conditionally (i.e. only for some errors).

 also a task can monitor child tasks for errors ( I don't think Rust
 has events but something like that) and choose on error to abort or
 continue depending on the error condition. .

Sounds interesting. I suspect (but I am not sure) that this is something
that could/should be built on top of a more elementary issue mechanism.
Could you provide a scenario that we could use as a working base?


 * The system _should_ eventually have a low runtime cost – in
 particular, the case in which no killing happens should be very fast.

 I don't think the performance of an error system is important at all ,
 its more important to have stack and meta data to resolve the issue
 especially in debug builds ( and meta data is very slow) .  This leads
 to people using errors to pass/check  state which is a bad habit

Could you elaborate on that last sentence?

I am starting to believe that collecting [meta]data might be something
that we want to configure on a usage basis. For instance, in function
|move|, introduced a few e-mails ago (I just reposted it at
https://gist.github.com/2781413 for convenience), we may be interested
in the metadata of calls to lines 10 and 12, but gathering metadata for
the calls in lines 2 and 6 is generally a waste of resources.

If we think of this as exceptions, it could be that we want several the
ability to specify if/when we want to gather metadata at the level of an
equivalent of |try|. I believe that this fits nicely with what Graydon
had in mind, by the way.

 I would add
 * Tasks are the error scope / unit

 * should we have an exception like syntax that automatically creates a
 

Re: [rust-dev] Back to errors, failures and exceptions

2012-05-24 Thread Brian Anderson

On 05/24/2012 06:16 AM, David Rajchenbach-Teller wrote:

On 5/24/12 12:40 PM, Bennie Kloosteman wrote:

* The system _must_ not prevent developers from calling C code from Rust.
* The system _must_ not prevent developers from passing a pointer to a
Rust function to C code that will call back to it.
* The system _must_ not prevent, some day, developers from calling Rust
from JavaScript.
* The system _must_ not prevent, some day, developers from calling
JavaScript from Rust.


These should be unsafe - I believe this is the case with rust.


I am not sure if you mean this in relation with all four points or with
the last one. So, indeed, I see no reason to change the fact that calls
to C are considered unsafe.


Calls to C are considered safe currently, an arrangement I disagree with.

-Brian
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Back to errors, failures and exceptions

2012-05-23 Thread David Rajchenbach-Teller
Actually, one of the conclusions of our previous discussion is that
Java/C++/ML-style exceptions are probably not what we want for Rust. I
seem to remember that we also concluded that using failures as
exceptions was probably not the right course.

Hence this new thread :)

Let me put together what I believe are a few desirable qualities of an
issue management system. For the moment, let's not wonder whether that
system is a language feature, a library or a coding guideline.

* The system _must_ not prevent developers from calling C code from Rust.
* The system _must_ not prevent developers from passing a pointer to a
Rust function to C code that will call back to it.
* The system _must_ not prevent, some day, developers from calling Rust
from JavaScript.
* The system _must_ not prevent, some day, developers from calling
JavaScript from Rust.
* Issues _must_ not be restricted to integers (or to one single type).
* The default behavior in case of untreated issue _should_ be to
gracefully kill the task or the application.
* Whenever an untreated issue kills a task/application, it _should_
produces a report usable by the developer for fixing the issue.
* It _should_ be possible to deactivate that killing behavior. There
_may_ be limitations.
* It _should_ be possible to deactivate that killing behavior
conditionally (i.e. only for some errors).
* The system _should_ eventually have a low runtime cost – in
particular, the case in which no killing happens should be very fast.


Do we agree on this base?

Cheers,
 David

On 5/22/12 4:56 AM, Bennie Kloosteman wrote:
 Are exceptions a good model for systems programming ?
 
 - legacy C programs cant call you without a wrapper which translates
 all possible exceptions
 - unwinding a stack is probably not a good idea in a kernel or when
 you transition into protected/user mode.( I know of very few kernels
 that use exceptions ).
 - Its not just legacy , Winrt uses C++ classes but returns error codes
 tor low level APIs.
 
 However its very nice for user programs . These days these different
 worlds works quite well , c libs which Is mainly used for system
 programming don't use them  and C++ apps are more user programs and
 they do  , C++ calls C , C rarely calls C++. Obviously if you write a
 kernel or shared library  you cannot use exceptions if  c programs
 call your code and there is a lot of c out there While not really
 an issue for the language ( just dont use exceptions) it means a
 standard lib that throws an exception would be a pain for such work
 and you would need a different standard lib , which is an issue .
 
 BTW could Rust use tasks as a substitute for exception scopes ? Tasks
 have error bubbling , hiding  , stack unwinding  , throw ( fail) and
 should have integrated logging . You could put a sugar syntax around
 it but it would still work when being called by c.  Also with tasks
 you can cancel or do timeouts giving asynronous exceptions  which are
 really needed ( eg in most systems cancel a long running task is very
 anoying very long pause). and which most trivial exception
 implementations don't do ..Not sure if this is the right way but there
 seems a lot of overlap and it would work with C and systems
 programming,.
 
 Ben
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev


-- 
David Rajchenbach-Teller, PhD
 Performance Team, Mozilla



signature.asc
Description: OpenPGP digital signature
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Back to errors, failures and exceptions

2012-05-23 Thread Matthieu Monrocq
On Wed, May 23, 2012 at 2:47 PM, David Rajchenbach-Teller 
dtel...@mozilla.com wrote:

 Actually, one of the conclusions of our previous discussion is that
 Java/C++/ML-style exceptions are probably not what we want for Rust. I
 seem to remember that we also concluded that using failures as
 exceptions was probably not the right course.

 Hence this new thread :)

 Let me put together what I believe are a few desirable qualities of an
 issue management system. For the moment, let's not wonder whether that
 system is a language feature, a library or a coding guideline.


As a whole, this looks very good to me, I just have one quick question:


 * The system _must_ not prevent developers from calling C code from Rust.
 * The system _must_ not prevent developers from passing a pointer to a
 Rust function to C code that will call back to it.
 * The system _must_ not prevent, some day, developers from calling Rust
 from JavaScript.
 * The system _must_ not prevent, some day, developers from calling
 JavaScript from Rust.
 * Issues _must_ not be restricted to integers (or to one single type).


Could you explain what you mean by this ?

I suppose this is a direct jab at the horror that is errno and more in the
direction of being able to throw anything (possibly at the condition it
implements a given interface) ?


 * The default behavior in case of untreated issue _should_ be to
 gracefully kill the task or the application.
 * Whenever an untreated issue kills a task/application, it _should_
 produces a report usable by the developer for fixing the issue.
 * It _should_ be possible to deactivate that killing behavior. There
 _may_ be limitations.
 * It _should_ be possible to deactivate that killing behavior
 conditionally (i.e. only for some errors).
 * The system _should_ eventually have a low runtime cost – in
 particular, the case in which no killing happens should be very fast.


 Do we agree on this base?

 Cheers,
  David

 On 5/22/12 4:56 AM, Bennie Kloosteman wrote:
  Are exceptions a good model for systems programming ?
 
  - legacy C programs cant call you without a wrapper which translates
  all possible exceptions
  - unwinding a stack is probably not a good idea in a kernel or when
  you transition into protected/user mode.( I know of very few kernels
  that use exceptions ).
  - Its not just legacy , Winrt uses C++ classes but returns error codes
  tor low level APIs.
 
  However its very nice for user programs . These days these different
  worlds works quite well , c libs which Is mainly used for system
  programming don't use them  and C++ apps are more user programs and
  they do  , C++ calls C , C rarely calls C++. Obviously if you write a
  kernel or shared library  you cannot use exceptions if  c programs
  call your code and there is a lot of c out there While not really
  an issue for the language ( just dont use exceptions) it means a
  standard lib that throws an exception would be a pain for such work
  and you would need a different standard lib , which is an issue .
 
  BTW could Rust use tasks as a substitute for exception scopes ? Tasks
  have error bubbling , hiding  , stack unwinding  , throw ( fail) and
  should have integrated logging . You could put a sugar syntax around
  it but it would still work when being called by c.  Also with tasks
  you can cancel or do timeouts giving asynronous exceptions  which are
  really needed ( eg in most systems cancel a long running task is very
  anoying very long pause). and which most trivial exception
  implementations don't do ..Not sure if this is the right way but there
  seems a lot of overlap and it would work with C and systems
  programming,.
 
  Ben
  ___
  Rust-dev mailing list
  Rust-dev@mozilla.org
  https://mail.mozilla.org/listinfo/rust-dev


 --
 David Rajchenbach-Teller, PhD
  Performance Team, Mozilla


 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev


___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Back to errors, failures and exceptions

2012-05-23 Thread Brian Anderson

On 05/23/2012 05:47 AM, David Rajchenbach-Teller wrote:

Actually, one of the conclusions of our previous discussion is that
Java/C++/ML-style exceptions are probably not what we want for Rust. I
seem to remember that we also concluded that using failures as
exceptions was probably not the right course.

Hence this new thread :)

Let me put together what I believe are a few desirable qualities of an
issue management system. For the moment, let's not wonder whether that
system is a language feature, a library or a coding guideline.

* The system _must_ not prevent developers from calling C code from Rust.
* The system _must_ not prevent developers from passing a pointer to a
Rust function to C code that will call back to it.
* The system _must_ not prevent, some day, developers from calling Rust
from JavaScript.
* The system _must_ not prevent, some day, developers from calling
JavaScript from Rust.
* Issues _must_ not be restricted to integers (or to one single type).
* The default behavior in case of untreated issue _should_ be to
gracefully kill the task or the application.
* Whenever an untreated issue kills a task/application, it _should_
produces a report usable by the developer for fixing the issue.
* It _should_ be possible to deactivate that killing behavior. There
_may_ be limitations.
* It _should_ be possible to deactivate that killing behavior
conditionally (i.e. only for some errors).
* The system _should_ eventually have a low runtime cost – in
particular, the case in which no killing happens should be very fast.


Do we agree on this base?


These points sound sensible to me.

-Brian
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Back to errors, failures and exceptions

2012-05-21 Thread David Rajchenbach-Teller
I am currently implementing a low-level API for file handling, for the
Mozilla Platform. This API is based on libc/winapi (which do not have
exceptions) but itself throws exceptions in case of errors.

This causes any number of amusing/error-prone situations, in which the
implementation of the API combines functions that do not throw
exceptions (because these errors are expected to be handled immediately)
and functions that do throw exceptions (because we do not want to forget
reporting errors), |errno|-based error checking, etc.

For instance, let us consider the following (otherwise rather simple)
function |move|, whose role is to rename/move a file or a directory,
possibly across devices.

Function move(from, to, options)
1.   - If |options| specifies that we should not overwrite
2. - Attempt to |open| for reading |to|
3. - If the call succeeds, close file and bail out
(destination exists).
4. - If the call fails due to insufficient rights for opening |to|,
bail out (destination exists).
5. - If the call fails due to |to| being ill-formed or too long,
bail out (client error).
6.   - Call libc |rename(from, to)|
7. - If the call succeeds, we are done.
8. - If the call fails due to files not being on the same device,
proceed.
9. - If the call fails for any other reason, bail out (propagate
error as received).
10.  - Call function |copy|.
11.- If the call fails, bail out (error as received).
12.  - Call function |remove|.
13.- If the call fails, bail out (error as received).
14.  - We have succeeded


This simple function already illustrates the following cases:

- Call to |open|:
  - catch and ignore most errors;
  - propagate some errors;
  - turn success into an error.

- Call to |rename|:
  - catch and ignore one error;
  - propagate all other errors;
  - success is a success.

- Calls to |copy| and |remove|:
  - propagate all errors

Now, I have not encountered yet a scenario in which errors raised by
|rename| are handled/ignored in a fine-grained way, but this will
certainly happen.

Cheers,
 David


-- 
David Rajchenbach-Teller, PhD
 Performance Team, Mozilla



signature.asc
Description: OpenPGP digital signature
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Back to errors, failures and exceptions

2012-05-21 Thread Bennie Kloosteman
Are exceptions a good model for systems programming ?

- legacy C programs cant call you without a wrapper which translates
all possible exceptions
- unwinding a stack is probably not a good idea in a kernel or when
you transition into protected/user mode.( I know of very few kernels
that use exceptions ).
- Its not just legacy , Winrt uses C++ classes but returns error codes
tor low level APIs.

However its very nice for user programs . These days these different
worlds works quite well , c libs which Is mainly used for system
programming don't use them  and C++ apps are more user programs and
they do  , C++ calls C , C rarely calls C++. Obviously if you write a
kernel or shared library  you cannot use exceptions if  c programs
call your code and there is a lot of c out there While not really
an issue for the language ( just dont use exceptions) it means a
standard lib that throws an exception would be a pain for such work
and you would need a different standard lib , which is an issue .

BTW could Rust use tasks as a substitute for exception scopes ? Tasks
have error bubbling , hiding  , stack unwinding  , throw ( fail) and
should have integrated logging . You could put a sugar syntax around
it but it would still work when being called by c.  Also with tasks
you can cancel or do timeouts giving asynronous exceptions  which are
really needed ( eg in most systems cancel a long running task is very
anoying very long pause). and which most trivial exception
implementations don't do ..Not sure if this is the right way but there
seems a lot of overlap and it would work with C and systems
programming,.

Ben
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev