Hello,

I am a programmer at ArrayFire and we are in the process of writing a Rust wrapper for our GPU library. You can find the library code over here and the Rust wrapper code here. ArrayFire is based off an generic multi-dimensional object known as *array*. We are having trouble wrapping our head around Rust's error handling mechanism. Let me explain it with an example of Pi computation using Monte Carlo method.

C++ stub to do the Pi estimation looks like below.

```
try {
array x = randu(samples,f32);
array y = randu(samples,f32);
double pi_val = 4.0 * sum<float>(sqrt(x*x + y*y) < 1) / samples;
} catch (af::exception& e) {
printf("Exception thrown: %s\n", e.what());
exit(255);
}
```

Operations such as ***,+** in the above equation are element-wise.

First couple of lines using the Rust wrapper looks as below.

```
let samples = 20000000;
let dims = Dim4::new(&[samples, 1, 1, 1]);
let x = match af::randu(dims, Aftype::F32) {
Ok(v) => v,
Err(e) => panic!("Randu failed with code {:?}", e),
};
let y = match af::randu(dims, Aftype::F32) {
Ok(v) => v,
Err(e) => panic!("Randu failed with code {:?}", e),
};
let sq = match af::sqrt( &x * &x + &y * &y ) {
Ok(v) => v,
Err(e) => panic!("sqrt failed with code {:?}", e),
};
let comp = match af::le( &sq, 1) {
Ok(v) => v,
Err(e) => panic!("sqrt failed with code {:?}", e),
};
let mut div_res = match af::sum_all(&div_res) {
Ok(v) => v,
Err(e) => panic!("sqrt failed with code {:?}", e),
};
let pi_val = 4.0 * div_res / samples;
```

Now the part where equations such as below come into question.

```
4.0 * sum<float>(sqrt(x*x + y*y) < 1) / samples;
```

We currently have implemented **std::ops** for *Array* struct that allows us to write arithmetic operations on Array's, however they look different compared to C++ (which is natural i suppose, correct me if i am wrong). For example

```
z = x*x+y*y // C++
let z = &x * &x + &y * &y; // Rust
```

How do we approach error handling in such cases as above, or for that matter as in a simple case as below

```
let x = match af::randu(dims, Aftype::F32) {
Ok(v) => v,
Err(e) => panic!("Randu failed with code {:?}", e),
};
```

that enables us to use terse cascaded calls as below

```
let x = af::cos(af::randu(dims, Aftype::F32));
```

instead of doing the following.

```
let x = af::cos(match af::randu(dims, Aftype::F32) {
Ok(v) => v,
Err(e) => panic!("Randu failed with code {:?}", e),
});
```

Any suggestions are appreciated,

Thank you,

Pradeep.