passing on optional parameters

Maybe I'm too dense at the moment, is there an easy way to "pass on" optional parameters from one function to another?
I would like to be able to say something like
function foo(a,[b])
variable a, b
    return a+bar([b])   // or, possibly, bar(b=b)
end

function bar([b])
variable b
    if( ParamIsDefault(b) )
        b=2
    endif
    return b+1
end

but it seems that I have to use instead
function foo(a,[b])
variable a, b
    if( ParamIsDefault(b) )
        return a+bar(b=2)
    else
        return a+bar(b=b)
    endif
end

function bar([b])
variable b
    if( ParamIsDefault(b) )
        b=2
    endif
    return b+1
end

I thus have to call ParamIsDefault() twice although function foo() does not really care about parameter b.
More importantly, foo() has to know the default value for b, which could be computationally costly in a real-world example.

(Note: incidentally, calling bar(b=b) when b is actually default (as indicated by the comment in the first example) does not throw an error since a missing variable is automatically initalized to zero; in the contrived example above it would only give the "wrong" result foo(1)=2 instead of foo(1)=4 --- with optional string parameters, the syntax does throw an error)

Any suggestions?
Yes, I believe you have to call ParamIsDefault twice since both of your functions do care about b (i.e. they have different behavior depending on whether the optional parameter is set). You can rewrite much more concisely with the trinary conditional operator , though. This is an idiom I use all the time:

function foo(a,[b])
    variable a,b
    b = paramIsDefault(b) ? 2 : b
    return(a + bar(b=b))
end

function bar([b])
    variable b
    b = paramIsDefault(b) ? 2 : b
    return(b+1)
end
There should be no need for 'foo' to know default values; it must only call 'bar' appropriately. The following should be sufficient:
function foo(a,[b])
variable a, b
    if( ParamIsDefault(b) )
        return a+bar()
    else
        return a+bar(b=b)
    endif
end
 
function bar([b])
variable b
    if( ParamIsDefault(b) )
        b=2
    endif
    return b+1
end


Jeff
mswitkes wrote:
Yes, I believe you have to call ParamIsDefault twice since both of your functions do care about b (i.e. they have different behavior depending on whether the optional parameter is set). You can rewrite much more concisely with the trinary conditional operator , though. This is an idiom I use all the time:

function foo(a,[b])
    variable a,b
    b = paramIsDefault(b) ? 2 : b
    return(a + bar(b=b))
end

function bar([b])
    variable b
    b = paramIsDefault(b) ? 2 : b
    return(b+1)
end


That is a cool way to collapse the ParamIsDefault syntax!

This still has the downfall that foo must know in advance the default value of b in bar. That requirement could be rather difficult to keep in larger or more complex programming code.

For this reason, I can see why the ability for foo to pass its (otherwise empty) default parameter b on to bar to be recognized as such and without throwing an error would be useful.

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAHuntsville
jjweimer wrote:
This still has the downfall that foo must know in advance the default value of b in bar. That requirement could be rather difficult to keep in larger or more complex programming code.

For this reason, I can see why the ability for foo to pass its (otherwise empty) default parameter b on to bar to be recognized as such and without throwing an error would be useful.


You can do this too. I typically pass nan as a parameter for this purpose:

function foo(a,[b])
    variable a,b
    b = paramIsDefault(b) ? nan : b // NOTE CHANGE HERE
    return(a + bar(b=b))
end
 
function bar([b])
    variable b
    b = paramIsDefault(b) || numtype(b) ? 2 : b // NOTE CHANGE HERE
    return(b+1)
end
mswitkes wrote:
You can do this too. I typically pass nan as a parameter for this purpose:

function foo(a,[b])
    variable a,b
    b = paramIsDefault(b) ? nan : b // NOTE CHANGE HERE
    return(a + bar(b=b))
end
 
function bar([b])
    variable b
    b = paramIsDefault(b) || numtype(b) ? 2 : b // NOTE CHANGE HERE
    return(b+1)
end


I do this as well, and you can do the same thing with optional string parameters, passing them as empty strings. Since Igor 6.12 or so, you have been able to have lines like this:
b = selectstring(paramisdefault(b),b,"smith")


assuming b is a string variable.