I was recently reminded that the following "functions" are settable, and I was surprised (even though I've seen this before). So I thought that it is valuable to share this information.
There are three critical properties of symbolic constants:
The ability to tell that it is a numeric expression (
NumericQ[Pi] === True
).The ability to compute the value to any precision.
We can implement all three by direct assignment. Let the symbol sqrt2
represent $\sqrt{2}$:
SetAttributes[sqrt2, Constant]
NumericQ[sqrt2] = True;
N[sqrt2, prec___] := N[Sqrt[2], prec]
Note that it wasn't necessary to unprotect any symbols.
Now sqrt2
doesn't evaluate:
sqrt2
(* sqrt2 *)
But it can be computed numerically:
N[sqrt2, 100]
(* 1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641573 *)
It is numeric:
NumericQ[sqrt2]
(* True *)
Which means that many functions work well with it without the need for additional definitions:
Positive[sqrt2]
(* True *)
Im[sqrt2]
(* 0 *)
Integrate[Exp[-sqrt2 x], {x, 0, Infinity}]
(* 1/sqrt2 *)
Integrate wouldn't give the same result with an arbitrary symbolic parameter:
Integrate[Exp[-s x], {x, 0, Infinity}]
(* ConditionalExpression[1/s, Re[s] > 0] *)
And of course it works with Dt
Dt[sqrt2 x, x]
(* sqrt2 *)
Did I miss anything? If so, let me know!