I’m going to have to start getting kind of brutal cutting dicey things out of the system for Beta/One. So when I ran across the ARITY-OF routine and all its disclaimers and concerns, I thought “oh no, well this simple-seeming thing is more trouble than it’s worth, to explain and document…”
Classical Rebol doesn’t have it. People who want to know the arity of a function have to get WORDS OF the function, then count up to the first refinement, and then say “done”.
But you’re not done, because if you’re processing source you might have seen something like APPEND/DUP/PART. How do you ask for the arity of that, without calling it? Massive unsolved problem.
But, wait a minute…
It was unsolved back then. But there’s a lot to be said for doing things right.
>> parameters of :append == [series value /part limit /only /dup count /line] >> parameters of :append/dup == [series value count /part limit /only /line] >> parameters of :append/part == [series value limit /only /dup count /line] >> parameters of :append/part/dup == [series value limit count /only /line] >> parameters of :append/dup/part == [series value count limit /only /line]
…and so all we have to write is…
arity-of: function [ "Get the number of fixed arguments to an ACTION! (if not variadic)" return: [integer!] action [action!] ][ if variadic? :action [ fail "ARITY-OF cannot give an answer for variadic actions" ] arity: 0 for-each p parameters of :action [ if refinement? :p [break] arity: arity + 1 ] return arity ]
Exercise for the reader: try doing this in Rebol2/R3-Alpha/Red
>> map-each x [ append append/dup append/part append/dup/part append/part/dup ][ arity-of get x ] == [2 3 3 4 4]