-----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

Reply via email to