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$
5
  • $\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
    Commented Jun 4, 2015 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
    Commented Jun 4, 2015 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$ Commented Jun 4, 2015 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$
    – YoAn
    Commented Jun 4, 2015 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
    Commented Jun 5, 2015 at 10:20

1 Answer 1

3
$\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$
4
  • $\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$
    – YoAn
    Commented Jun 4, 2015 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$ Commented Jun 4, 2015 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
    Commented Jun 5, 2015 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$ Commented Jun 5, 2015 at 5:34

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.