8
$\begingroup$

I'm developing a function f which should support optional arguments {x_, y_} in list form. A simple example looks like this:

f[{x_, y_}] := {x, y}

How can I set default values for the list argument {x_, y_}? My first attempt was

f[{x_:1, y_:2}] := {x, y}

which matches f[{}] and correctly returns {1, 2} but which does not match f[].

How can I define the function f so that f[] gives the desired default values?

$\endgroup$
5
  • $\begingroup$ reference.wolfram.com/language/tutorial/… $\endgroup$
    – LLlAMnYP
    Commented Apr 17, 2015 at 13:35
  • $\begingroup$ add f[] = f[{}] later, it this ok? $\endgroup$
    – Kuba
    Commented Apr 29, 2015 at 8:26
  • $\begingroup$ This seems not to be a nice solution. There are many internal MMA functions like ImageTake which use optinal and default arguments in list form. Basically I want to implement the same functionality regarding optional arguments as in ImageTake, see the documentation. $\endgroup$
    – Robinaut
    Commented Apr 29, 2015 at 8:33
  • $\begingroup$ @Kuba Sorry for being unprecise. I'm just wondering if your solution is the "official" way to deal with optional list arguments like in ImageTake. I also tried f[args:{x_, y_}:{1,2}] := {x, y}which seems to work. However, I'm not sure if understand it the right way... $\endgroup$
    – Robinaut
    Commented Apr 29, 2015 at 11:07
  • $\begingroup$ @Robinaut Use Needs["GeneralUtilities`"]; and evaluate PrintDefinitions@Cells, as you can see, WRI is not trying to put everything in one pattern either. It is not handy nor readable. $\endgroup$
    – Kuba
    Commented Apr 29, 2015 at 11:14

2 Answers 2

3
$\begingroup$

Sorry for being unprecise. I'm just wondering if your solution is the "official" way to deal with optional list arguments like in ImageTake. I also tried f[args:{x_, y_}:{1,2}] := {x, y}which seems to work. However, I'm not sure if understand it the right way...

I do not believe I have seen a guideline or even a standard practice for this particular case. I quite like Kuba's solution and I often make use of that method, e.g.: Can I make a default for an optional argument the value of another argument?

You chose ImageTake as a model. For this function there is no need for the optional behavior that you describe as the syntax is already handled by Take. Note:

enter image description here

This syntax is valid for each argument of ImageTake (after the first) just as it is for Take. Therefore a trivial reimplementation is:

myImageTake[i : _Image | _Image3D, spec__] := 
  Head[i][Take[ImageData[i], spec], ColorSpace -> ImageColorSpace[i]]

Test:

img = Import["http://cdn.sstatic.net/mathematica/img/[email protected]"]  (* site logo *)

myImageTake[img, -66, {30, 120}]
ImageTake[img, -66, {30, 120}]

enter image description here

img3D = ExampleData[{"TestImage3D", "CThead"}];

myImageTake[img3D, -20, {80, 180}, 120]
ImageTake[img3D, -20, {80, 180}, 120]

enter image description here

If I wanted tighter control of the input than spec__ I would use something like:

p1 = (All | _Integer | {Repeated[_Integer, {1, 3}]})?(FreeQ[#, 0] &);

ClearAll[myImageTake]

myImageTake[i : _Image | _Image3D, spec : p1 ..] /; 
  Length[{spec}] <= Length@ImageDimensions[i] := 
    Head[i][Take[ImageData[i], spec], ColorSpace -> ImageColorSpace[i]]

This example may be a bit too specific but it is the one that you gave. For other examples the pattern you found (args:{x_, y_}:{1,2}) or the method of passing arguments back to the function (Kuba's answer and my linked post above) may be more appropriate. If you give another example or model function I shall try to address that as well.

$\endgroup$
7
$\begingroup$

There are many ways to achieve this, I'd probably do something simple like

f[] = f[{}] 
(*set or set delayed, depends of context*)

But you can also do something more fancy, although it is not compact enough for me to like it :P

Default[f] = {};
f[Optional@{x_: 1, y_: 2}] := {x, y}

f[]
f[{}]
{1, 2}
{1, 2}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.