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