4
$\begingroup$

Why this doesn't work?

k[x_Integer:2?(#>0&)]:=x^2
k[]  (*should be 4*)
k[2] (*should be 4*)

These following are all working as expected:

(* with Optional *)
f[x_Integer:2]:=x^2
f[]
(* with PatternTest *)
g[x_Integer?(#>0&)]:=x^2
g[2]
(* with Optional + Condition *)
h[x_Integer:2]:=x^2/;x>0
h[]
h[2]
$\endgroup$
  • 4
    $\begingroup$ ClearAll[k]; k[x : _Integer?(# > 0 &) : 2] := x^2? $\endgroup$ – kglr Aug 29 at 17:12
  • 2
    $\begingroup$ That can also be written as k[x : _Integer?Positive : 2] := x^2 $\endgroup$ – Bob Hanlon Aug 29 at 17:16
  • $\begingroup$ ... or ClearAll[k2];k2[Optional[x_Integer?Positive, 2]] := x^2 $\endgroup$ – kglr Aug 29 at 17:16
  • 2
    $\begingroup$ see k[x_Integer: 2?(# > 0 &)] // FullForm and Precedence /@ {Optional, Pattern, PatternTest} $\endgroup$ – kglr Aug 29 at 17:18
1
$\begingroup$

It doesn't work because : can have two meanings in an argument form, Optional and Pattern, and the front-end has trouble deciding which is meant when two : appear in such an argument.

You can fix the issue by writing Optional in full form. Like so:

Clear[k]; k[Optional[x_Integer?Positive, 2]] := x^2; {k[], k[2], k[-2], k[2.]

{4, 4, k[-2], k[2.]}

You might also want to consider some alternatives.

Clear[k]; k[x_Integer : 2] /; x > 0 := x^2  
Clear[k]; k[x_ : 2] /; x ∈ PositiveIntegers := x^2
Clear[k]; Default[k] = 2; k[x_.] /; x ∈ PositiveIntegers := x^2
| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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