1
$\begingroup$

I'm a beginner in Mathematica programming and I'm trying to understand how input parameters work in Mathematica's function.

I encountered a problem with the sequence/order of the input parameters of functions.

I tried to change the sequence/order of parameters (like I were used to do in Python codes) but I couldn't find the way to do it in the help of Mathematica or in the forum.

This is an example of what I'm trying to do:

foo = Function[{a,b,c},
    Block[{result},
         result=a+b-c;
         result
    ]
]

I would like to obtain this result:

foo[1,2,3] -> 0
foo[c=3,a=1,b=2] -> 0

But this way, that I was using in Python, is not working.

Does anybody know if it is possible and how please?

Thanks.

Edit : Thanks for people who corrected my post.

$\endgroup$
  • $\begingroup$ Welcome to Mathematica.SE! I hope you will become a regular contributor. To get started, 1) take the introductory Tour now, 2) when you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge, 3) remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign, and 4) give help too, by answering questions in your areas of expertise. $\endgroup$ – bbgodfrey Jun 4 '15 at 17:34
  • $\begingroup$ I'm not sure why you're showing such an unnecessarily elaborate definition for foo. Why not just: foo[a_, b_, c_] := a + b - c? That's the ordinary way of defining a function in Mathematica. Is there some reason you're using a "pure function" construction? $\endgroup$ – murray Jun 4 '15 at 17:36
  • $\begingroup$ In addition to what @murray already said, you've a missing colon after the parameter list: foo = Function[{a, b, c}, Block[{result}, result = a + b - c; result]] $\endgroup$ – Dr. belisarius Jun 4 '15 at 18:55
  • $\begingroup$ I used the same elaborate definition I'm using for the more complex function I'm trying to build and sorry for my mistake. Thanks for your comments. $\endgroup$ – Tyrannax Jun 4 '15 at 21:04
  • $\begingroup$ @murray I have to disagree with your comment. This is relevant. I personally try to use pure functions whenever possible to improve performance. $\endgroup$ – LLlAMnYP Jun 5 '15 at 10:20
2
$\begingroup$

Arguments in Mathematica are passed in the order they are declared. There is no basic method in the language that allows you to name your parameters as in Python.

This does not mean that you cannot mimic the calling methods of Python. You can use at least two ways to do that.

First, the standard definition of your function:

foo[a_,b_,c_]:=a+b-c

foo[1, 2, 3]

0

Now the orderless call using Association (version 10).

foo[arg_Association] := arg[a] + arg[b] - arg[c]

foo[<|c -> 3, a -> 1, b -> 2|>]

0

foo[<|c -> 4, a -> 3, b -> 2|>]

1

Using a list:

foo[lis_List] := a + b - c /. lis

foo[{c -> 3, a -> 1, b -> 2}]

0

foo[{c -> 4, a -> 3, b -> 2}]

1

Providing default values using the last method:

foo[lis_List] :=  a + b - c /. lis /. {c -> 10, a -> 20, b -> 30}

foo[{c -> 3, a -> 1}]

28

There are of course issues if a, b, c are already defined. It all becomes a little bit more complicated. First localizing a, b, c:

foo[lis_List] := Block[{a, b, c}, a + b - c /. lis /. {c -> 10, a -> 20, b -> 30}]

There are still problems during the call if for instance already has a value say 5:

foo[{c -> 3, a -> 1, b -> 2}] 

then turns into a call

foo[{5 -> 3, a -> 1, b -> 2}]

yielding -5.

Without rule for c the default value kicks in unintentionally. One solution would be to prevent evaluation of the argument using HoldAll or HoldFirst:

SetAttributes[foo, HoldFirst]

c = 5

5

foo[{c -> 4, a -> 3, b -> 2}]

1

$\endgroup$
  • $\begingroup$ Thanks a lot for your help ! It really helped me to understand how it works. I only have the version 9 of Mathematica so i will use your second proposition. Indeed i planned to do that to use default values, so thanks for reading my mind ;) $\endgroup$ – Tyrannax Jun 4 '15 at 21:00
  • $\begingroup$ You're welcome. I'd suggest not to try to transplant too much of one language's constructions in the other. Solutions won't be optimal in many cases. $\endgroup$ – Sjoerd C. de Vries Jun 4 '15 at 21:15
  • $\begingroup$ What's wrong with defining foo[a_, b_, c_] := a + b - c and then using any values for the 3 arguments you wish. Thus foo[[5, 1, 2] gives 4 but foo[5, 2, 1] gives 6. In other words, when you call foo just permute the inputs as you desire. $\endgroup$ – murray Jun 5 '15 at 0:45
  • $\begingroup$ @murray The OP wanted the Python way of doing it, which allows for orderless input of arguments. The main advantage is, I guess, that for large arguments lists it's easier to see which value goes to which variable. Otherwise, you'll have to do a lot of counting. Mathematica does something like this with a function like FinancialDerivative. $\endgroup$ – Sjoerd C. de Vries Jun 5 '15 at 5:34

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.