Hello,
I'm working on bindings for the API (for zig), and was wondering if the
R's C API guarantees it won't return null pointers?
The only reference I found in the "Writing R Extensions" manual where
this not the case is `R_tryEval` and `R_tryEvalSilent`.
Otherwise it's unclear.
The reason I care about this is syntax. Because I don't know whether SEXPs
are NULL or not, then I wrap the SEXP in an optional type, and the burden is on
the user to either check or assert every time you want to handle an optional
SEXP.
It's not too bad and provides null safety, but can get excessive.
See an example from one of my test functions (question mark unwraps the
optional. asserting it is not null):
```
export fn testAsScalarVector() Robject {
const results = rzig.vec.allocVector(.List, 23).?.protect();
defer rzig.gc.protect_stack.unprotectAll();
results.?.setListObj(0, rzig.vec.asScalarVector(@as(f32, 1.32456e+32)));
results.?.setListObj(1, rzig.vec.asScalarVector(@as(f32, -9.87123e-32)));
results.?.setListObj(2, rzig.vec.asScalarVector(math.inf(f32)));
results.?.setListObj(3, rzig.vec.asScalarVector(-math.inf(f32)));
results.?.setListObj(4, rzig.vec.asScalarVector(math.nan(f32)));
results.?.setListObj(5, rzig.vec.asScalarVector(@as(f64, -9.1e+300)));
results.?.setListObj(6, rzig.vec.asScalarVector(@as(f64, 1.2e-300)));
results.?.setListObj(7, rzig.vec.asScalarVector(math.inf(f64)));
results.?.setListObj(8, rzig.vec.asScalarVector(-math.inf(f64)));
results.?.setListObj(9, rzig.vec.asScalarVector(math.nan(f64)));
results.?.setListObj(10, rzig.vec.asScalarVector(-9.1e+307));
results.?.setListObj(11, rzig.vec.asScalarVector(1.2e-307));
results.?.setListObj(12, rzig.vec.asScalarVector(1.0e+500)); // Inf
results.?.setListObj(13, rzig.vec.asScalarVector(-1.0e+500)); // -Inf
results.?.setListObj(14, rzig.vec.asScalarVector(5));
results.?.setListObj(15, rzig.vec.asScalarVector(-5));
results.?.setListObj(16, rzig.vec.asScalarVector(@as(u32, 4)));
results.?.setListObj(17, rzig.vec.asScalarVector(@as(i32, -4)));
results.?.setListObj(18, rzig.vec.asScalarVector(@as(u0, 0)));
results.?.setListObj(19, rzig.vec.asScalarVector(@as(u150, 2_000_000_000)));
results.?.setListObj(20, rzig.vec.asScalarVector(@as(i150,
-2_000_000_000)));
results.?.setListObj(21, rzig.vec.asScalarVector(true));
results.?.setListObj(22, rzig.vec.asScalarVector(false));
return results;
}
```
It would be nice to be able to drop the question mark, but only if R guarantees
null safety at the API level. Then I would declare optional return types only
for documented cases like `R_tryEval`
Appreciate your time an help!
Thanks,
- Erez