Skip to content
Prev 58930 / 63424 Next

some questions about R internal SEXP types

Thanks, Gabriel.
On Mon, 2020-09-07 at 14:38 -0700, Gabriel Becker wrote:
This is helpful. Currently this will work in the low level SEXP API,
though not in the hand-holding level (and I think this is probably a
reasonable behavioural distinction); in the low level SEXP API in
rgo/sexp there are two facilitated ways to return values to R, the
Value.Pointer method and the Value.Export method, the first returns
whatever the value of the SEXP is, C NULL, R_NilValue or non-null
result, the second converts C NULL to R_NilValue before returning.
However, in line with the Go philosophy of not doing too much, the user
is free to return a Go nil (equivalent to a C NULL) or anything else if
they want.

The Pointer method is a pure type conversion:

```
func (v *T) Pointer() unsafe.Pointer {
	return unsafe.Pointer(v)
}
```

and the Export method was an addition I made when I accidentally
returned a nil during testing and the R runtime complained at me.

```
func (v *T) Export() unsafe.Pointer {
	if v == nil {
		return NilValue.Pointer()
	}
	return unsafe.Pointer(v)
}
```

These are really just helpers that mean users don't need to use the Go
unsafe package directly for anything other than making their function
signatures valid.

Similarly, the parameter passed in to Go can be C NULL, R_NilValue or a
non-null value. It's a little more work in the case that C NULL needs
to be distinquished from R_NilValue:

```
func UserGoCode(p unsafe.Pointer) unsafe.Pointer {
	if p == nil {
		// We have a C Null.
		// If this condition is omitted, v below will be
		// R_NilValue when p is nil.
	}
	v := (*sexp.Value)(p).Value()
	// We have v as a type that is one of the R TYPE values.
	...
```
This should be OK from what I've said above. What the user won't be
able to do is distinguish between C NULL and R_NilValue in values that
come from. So I guess a better phrasing of my original question is
whether valid SEXP value fields ever hold C NULL. If they do, then I
have a problem. I'm very much hoping that some kind of sanity in the
code prevails and this doesn't ever happen.
I have not looked at all at ALTREP (though it looks like it would be
valuable given the goal of the project), but as above, I *can* return
the C NULL.
Is this still a concern with my clarifications above?

thanks
Dan
Message-ID: <f9bbef0288a54a3ea87d56fd56ffbcf6c56c1e40.camel-8052@kortschak.io>
In-Reply-To: <CAD4oTHHs0QoJ4FuWB4t_k-8AFiA2ECR2dHRWOO6Phiiio7AMew@mail.gmail.com>