[xquery-talk] best practice for function design with many optional params

Jakob Fix jakob.fix at gmail.com
Thu Jan 26 14:04:13 PST 2012


On Thu, Jan 26, 2012 at 20:31, James Fuller <james.fuller.2007 at gmail.com> wrote:
> On Thu, Jan 26, 2012 at 9:13 AM, Jakob Fix <jakob.fix at gmail.com> wrote:
>> Hello,
>>
>> I'm confronted with the design of a function library where many
>> functions have loads of optional arguments.
>>
>> I understand in XQuery I can create any number of functions with the
>> same name as long as the signature is differentiated by the number of
>> arguments. This is cumbersome if I have many arguments, and also if
>> there is no precedence (i.e. the third optional param could appear on
>> its own without the first or second param being required).
>>
>> f:func( $req1, $opt1, $opt2, $opt3 )
>> f:func( $req1, $opt1 )
>> f:func( $req1, $opt1, $opt2 )
>>
>> would work, but what about
>>
>> f:func( $req1, $opt2 )
>> f:func( $req1, $opt2, $opt3 )
>> f:func( $req1, $opt3 )
>>
>> another option would be to use a sequence:
>>
>> f:func( $req1, $seq1 as item()* )
>>
>> but it's still difficult to make sense of parameters passed as they
>> cannot be identified as no name and position is non-significative
>>
>> the "least evil" solution seems to be for me right now:
>>
>> f:func( $req1, $params as element(params) )
>>
>> where $params := <params><opt1>a</opt1><opt2>b</opt2><opt3>c</opt3></params>
>> advantage here is to have explicit parameter names and it's easy to
>> make sense of them.
>> but drawbacks are it's quite more verbose, and all the verification
>> has to be done by the function body
>>
>> I haven't really looked at maps (they are planned for XQuery 3.0 I
>> think), what would their advantage be over the node approach? Any
>> other ideas or pointers for more information?
>
> as others have said, maps would be ideal ...
>
> past that, I think in any programming language, its kind of a 'bad
> smell' when a function has a very long signature ...  are you sure all
> these options are intrinsic to your function (in this sense its
> analagous to the questions we ask ourselves in OO lang when defining a
> class, its members and functions).
>
> I would suggest;
>
> * can you decompose your function into several functions ? this can
> have a beneficial decoupling
>
> * the approach MKay defined (e.g. element with lots of attributes) is
> the best way to do it, but make sure you group your options along
> logical lines (perhaps cross cutting across several functions)
>
> * w/o seeing your actual function logic, you may find it useful to
> pass in a function versus a bunch of variables
>
> * can is the primary data ($req1) your function is working on be
> decomposed ... it maybe that you are trying to achieve a lot of things
>
> * have you tried unit testing ... this can help discover the right
> 'grain' your functions should work at e.g. I find myself often
> refactoring a function when I have unit tests in affect ... also unit
> tests can help you look at a functions responsibility from different
> angles
>
> gl, J

Jim,
thanks for your input. right now, I'm mapping an existing api to
xquery, therefore I'd like to stick to the original signatures if at
all possible. Later on, convenience functions could be imagined, of
course.  I do use unit testing (xqut right now, although I'm tempted
to give x-ray a try, both admittedly MarkLogic-specific).

cheers,
Jakob.



More information about the talk mailing list