Search code examples
maple

Dealing with more than one Optional parameter


I have a procedure

f:=proc(x,option1,option2) ... end proc;

In my case option1 is always an integer and option2 is either a list or something else (including integer). Both options are optional, so these commands work as expected:

f(x);
f(x,3);
f(x,4,[1,2]);
f(x,5,3);
f(x,6,expand);

But if option1 isn't specified then I don't know an easy way to deal with it since Maple doesn't allow the usage like

f(x,,3);
f(x,,[1,2]);

I can make it understand

f(x,[1,2]);

but I still have a problem with

f(x,3);

since it's not clear if 3 is option1 or option2. I can rewrite the code to understand function calls in this format

f(x,[1,option1],[2,option2]);
f(x,[1,option1]);
f(x,[2,option2]);

but I'm curious if there is a simpler way to achieve that since for some Maple functions (like plot) the order of most options doesn't matter.


Solution

  • Most of the plotting commands use Maple's more modern argument-processing to manage procedure options.

    In particular most options to plotting commands are provided as so-called keyword options. That automatically provides the functionlity in which the location (of such options) doesn't matter.

    For example,

    f:=proc(v, 
            {ord::{integer,NoUserValue}:=':-NoUserValue'},
            {special::{integer,list,NoUserValue}:=':-NoUserValue'});
    
      print(':-ord'=ord, ':-special'=special);
    
    end proc:
    
    f(x);
    
        ord = NoUserValue, special = NoUserValue
    
    f(x,ord=3);
    
             ord = 3, special = NoUserValue
    
    f(x,special=5);
    
             ord = NoUserValue, special = 5
    
    f(x,special=5,ord=3);
    
                   ord = 3, special = 5
    
    f(x,ord=3,special=5);
    
                   ord = 3, special = 5
    

    As you've noticed, you [logically] cannot use multiple *positional/ordered" parameters if both have the same type and some earlier ones are missing.

    If you really wanted you could make one of those options into a positional parameter, although naturally that would lose its flexibility of arbitrary placement. For example,

    restart;
    f2:=proc(v, 
            ord::{integer,NoUserValue}:=':-NoUserValue',
            {special::{integer,list,NoUserValue}:=':-NoUserValue'});
    
      print(':-ord'=ord, ':-special'=special);
    
    end proc:
    f2(x);
    f2(x,3);
    f2(x,special=5);
    f2(x,special=5,3);
    f2(x,3,special=5);
    
    restart;
    f3:=proc(v, 
             special::{integer,list,NoUserValue}:=':-NoUserValue',
             {ord::{integer,NoUserValue}:=':-NoUserValue'});
    
      print(':-ord'=ord, ':-special'=special);
    
    end proc:
    f3(x);
    f3(x,5);
    f3(x,ord=3);
    f3(x,ord=3,5);
    f3(x,5,ord=3);
    

    There are too many variants to show them all here, sensibly.

    You don't have to use the name "NoUserValue" as the default values.