Should Refinement Callsites Use VOID-in-NULL-out?

So yes, this turns out to be the best idea.

And with <undo-opt> as a parameter option, you have a smooth curve for converting a parameter between being a refinement and not a refinement. You get it as null internally to the function either way, making it pleasant to handle while preventing accidents on the interface:

foo: func [x [<undo-opt> integer!]] [
    if null? x [print "null"] else [print ["integer:" x]]
]

>> foo 10
integer: x

>> foo void
null

>> foo null
** Error: FOO doesn't accept NULL for its X argment

So now if you change X to be a refinement, you have the same VOID-in-NULL-out behavior.

What this means is that if you want either a refinement or an <undo-opt> argument to be specialized out to null, you have to use meta-void when constructing the frame. You don't actually pass meta-null.

The meta-representation in frames up until the "last mile" is a significant new development, and allows you to pass those voids as frame.^refine: void

Meta-Parameters And Function Composition - #3 by hostilefork