So this was never the craziest idea.
I think it gets a little less ugly now that we're talking about using :word
for refinements
func ['foo [<end> word!] :bar [integer!] :no-arg] [...]
=>
func [foo '[<end> word!] bar :[integer!] no-arg-refinement :[]] [...]
I think getting the typespec blocks in this form makes sense, it will allow code that wants to do its own processing of functions to get what it needs.
But in the function spec dialect, I think it's still probably superior to decorate the words. But perhaps you could choose either in the spec...it might be more convenient in generated code to be able to splice the parameter convention on with the types instead of decorate the word.
So unspecialized slots now hold what are actually PARAMETER! antiform types... not blocks. If you were putting actual BLOCK!s in the frame, then those would be specialized as blocks. If you were putting non-antiform parameters in those slots, they'd be specialized as parameter descriptions.
I don't know what parameters should render like, but for the moment they're the same lame idea as everything else that isn't structurally trivial... e.g. #[parameter! [~null~ any-value?]]
Unfortunately, this means the previously elegant-looking ~ for unspecialized parameters is now rather ugly (albeit informative!). And things like DEFAULT need to treat antiform parameters as being not there (but it has to do that for antiform tags as well, so...)
Another three years downstream...
-
The elimination of TYPESET! and using intrinsic-powered typechecking with the PARAMETER! type means we preserve the whole type spec block for processing directly
-
The elimination of skippable parameters helps remove a difficult-to-simulate behavior for anyone trying to reason about the behavior of an argument.
There's still some curveballs, in terms of whether your abstraction knows every weird behavior-controlling TAG! we might throw in now or in the future. But it's definitely a lot closer to reality now.