The Meaning of JavaScript's "Undefined" in the API

Something that has been kind of on my mind is the relationship between JavaScript's undefined and n-C's trash state.

I've set it up so that if you have a JS-NATIVE that doesn't have a return statement, that returns trash. That's consistent with plain functions that don't have a return statement.

However, it seems to me that reb.Value("print {Hello}"); should not return undefined the way that reb.Value("select [a 10 b 20] 'c"); returns null. One reason is because JavaScript is bad about conflating falsey things, and it considers undefined to be falsey. So it is probably good to have only one falsey result that can come back from running arbitrary code.

It also seems like it's probably better to error on undefined when given as an argument:

function foo() { }
reb.Elide("append data", foo())

Would you rather that run without error, appending a trash to data, or have reb.Elide() complain that an argument is undefined?

Guess my point is that it seems like an area where noticing the parallel is useful, but care should be taken in where to make the mapping apply...

Years after the original post, the model has changed. (Though note that I retroactively update posts to reflect modern terminology if it helps make the points easier to understand.)

The new situation is that trash is an "antiform isotope". So you can't append it.

You could assign it to a variable, if you qualify the insertion with something like a meta or @ :

function foo() { }
reb.Elide("obj.field: @", foo())

If you go through that, should it be an error or should obj.field be the Ren-C concept of "undefined", e.g. set to a trash antiform?

It really hasn't come up yet, so no immediate action is needed. But at least it now seems more safe, since undefineds can't accidentally get passed as easily.

1 Like