-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Tue Nov 15 15:30:34 2011, Niko Matsakis wrote: > Yes, I was thinking something similar yesterday. Such a pattern > might well be perfect.
I have just submitted a blocker issue https://github.com/graydon/rust/issues/1176 Syntax-wise, let's write this as follows let x = #do[e] ...and explore possible issues. 1/ Mixing and matching distinct kinds of errors As such, not too good: foo() -> result::t<A, IOError> bar() -> result::t<B, ArithError> { let x = #do[ foo() ] let y = #do[ bar() ] ... } this will cause a type error. Unless there are plans to implement open sums, which I doubt, we need to impose that the second member of `result::t` has a predictable type. At the moment, the only extensible predictable type that I know of is `any` (or some ADT built on top of it). In the future, we will probably have interfaces and RTTI to differentiate them. Both options seem acceptable to me. For the moment, let's call `exn` the type of exceptions. 2/ Syntax I suggest we manipulate it only through the following macros (here displayed with their pseudo-type and ret): #do[expr] //Continue if `expr` succeeds, propagate exception otherwise //If `expr` has type result::t<A, B>, this has type A and // returns result::t<A, B> #throw[err] //Throw exception //If `err` has type A, this has type `any` and // returns result::t<any, B> #success[val] //Returns a success //If `val` has type A, this has type result::t<A, any> // returns any #catch[expr, handler] //Catch some exceptions, maybe not all //If `expr` has type result::t<A, B> //and `handler` has type block(exn) -> result::t<A, C> //this has type A //and returns result::t<A, C> #try[expr] //Leave the world of exceptions //If `expr` has type result::t<A, B> //this has type A //and fails if `expr` has evaluated to an error Example: fn div(a: int, b: int) -> result::t<int, arith_error> { if x == 0 { #throw[ arith_error(division_by_zero) ] } #success[ a / b ] } fn write_int(a: int) -> result::t<nil, io_error> { //... } fn main() { #try[ #catch[[ let x = #do[div(5,10)] + #do[div(5,30)]; #do[write_int(x)]; #success[()] ]]{|e| -> //log error } ] } Ok, that is still a bit heavy, syntax-wise. Any idea on how to improve this? 3/ Debugging aid Let us return to the definition of exceptions. Once we have safely semi-abstracted our definition of exceptions behind macros, we can define `exn` for instance as follows type exn = { spec: any //Exception-specific data //or some root interface and RTTI text: option::t<string> //Optional description #cfg[debug] stack: @list::t<pos> //Stack information } Which would essentially give us the debugging power of Java exceptions. Any thoughts? Cheers, David -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (Darwin) iQEcBAEBAgAGBQJOwsUoAAoJED+FkPgNe9W+0w0H/jKb52dHf5YTE0lPxW13h4NI jhy+qF6pBIXg9bkLsQOVWJzpGTdahKqVOvfIjLEnAQvpDDd3HaHkZbegB9Yc4BQ9 JmPzLB9GvedJoTcXlNaWfmecpjYZZPzZvtfVl0/m3dfathiJBZdValRjlQuKI7V0 x+DXTVEWybBZraRi0dUtIduTfqC8B/OYK6qoOTCHlaVA+/43QHXkbvtLYYIE2+V2 g4uGBl+47hlt4tEdumNvclfqmbeze7fpMMgB4HhdjR3+L28OdQNvWzQgb009/4aA CNQ8BGCTkJ7Z1d7dNw8sFrZm0/uIMwiSo/QDGQQ3U8btWYFnEZOoeo1L6szqgKM= =Et5p -----END PGP SIGNATURE----- _______________________________________________ Rust-dev mailing list [email protected] https://mail.mozilla.org/listinfo/rust-dev
