2
$\begingroup$

With respect to code readability I like the possibility to use keyword (named) arguments.

I would like to have this under Mathematica, but AFAIK there is no native support for that.

By example, to define an inverse gamma distribution, I come with this approach:

createInverseGamma[Mean->m_,Variance->v_]:=
  With[{a=(m^2+2v)/v,b=m (m^2+v)/v},InverseGammaDistribution[a,b]];

createInverseGamma[Mean->m_,StandardDeviation->std_]:=
  createInverseGamma[Mean->m,Variance->std^2];

dist=createInverseGamma[Mean->1,StandardDeviation->2]

Mean[dist]             (* 1 *)
Variance[dist]         (* 4 *)

My question: do you see some drawbacks to this approach or do you have a better solution?

nb:

  • clearly some symbols have to be reserved and protected (here I use Mean, Variance etc... that are already defined).
  • this approach can interfere with Option, maybe it would be better to define something like foo[Mean=5] with "=" instead of ->

update:

here is an example with "=" instead of ->

SetAttributes[createInverseGamma,HoldAll];

createInverseGamma[Mean=m_,Variance=v_]:=
  With[{a=(m^2+2v)/v,b=m (m^2+v)/v},InverseGammaDistribution[a,b]];

createInverseGamma[Mean=m_,StandardDeviation=std_]:=
  createInverseGamma[Mean=m,Variance=std^2];

dist=createInverseGamma[Mean=1,StandardDeviation=2]

Mean[dist]             (* 1 *)
Variance[dist]         (* 4 *)

However I am even less sure that it has no deleterious side effect...?

$\endgroup$
4
  • $\begingroup$ "[...] it is usually possible to provide the values in any arbitrary order, [...]" - that's not the case here, right? You could use KeyValuePattern[{Mean -> m_, ...}] instead but I find KeyValuePattern quite code-obscuring. The call would have to have a single argument as well. $\endgroup$ – Kuba Dec 10 '20 at 11:28
  • $\begingroup$ @Kuba thank you for the comment, I will try. With "named" arguments I can accomodate any solution (with or without order restriction), I just want the approach to have no deleterious side effect and improve code readability (at least on the caller side). $\endgroup$ – Picaud Vincent Dec 10 '20 at 11:38
  • $\begingroup$ Could use strings for the names in the rule-based version, e.g. createInverseGamma["Mean"->m_,"Variance"->v_]:=... Not sure if this will achieve what you want though. $\endgroup$ – Daniel Lichtblau Dec 10 '20 at 13:51
  • $\begingroup$ @DanielLichtblau A priori I do not want to use strings as you cannot use pattern matching anymore. By example it is impossible to distinguish foo["Variance"->_] versus foo["Mean"->_] by example (AFAIK). $\endgroup$ – Picaud Vincent Dec 10 '20 at 14:02

Your Answer

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

Browse other questions tagged or ask your own question.