The patch did work. But, I don't like the way previously defined vars are handled. Plus, most languages enforce the rule that a function call needs the same number of params as the function definition ... EXCEPT when you have supplied default values. So, again, with your original example you just have to create the function with 1 or 2 default value functions ...
Now, it might be worthwhile discussing a method to provide NULL values in a default value. But, then, even if we do this, I'm not sure how we'd get MMA's if/then stuff to easily deal with it.
Yes, having to check against a arbitrary string value is ugly ... I'm just not sure of an easier way. Getting back to your original example:
DefCall Foo Arg=__OMITTED__
If Ne $$Arg __OMITTED__
...called with argument...
Else
...called without argument...
Endif
EndDefCall
Would changing the initial test to "If eq Arg __OMITTED__" be that much uglier than "If def A". Hint, you don't need "$$". Even more elegant, maybe!, is the code in egs/subroutines/convert4to5.mma which uses an array?
Try this with a real language like python ...
def foo(a,b,d):
print(a)
foo(a)
and you'll see the same behavior .. unless you do something like "def foo(a,b=None, c=None)" in which case we're down to my point.