Can I automatically lazily evaluate function parameters in Mathematica?

In Mathematica, I would like to do something like:

f[Rational[a_, b_], Rational[c_, d_]] := {a+c, b+d} 

But if I evaluate it using expressions of the following form, I get the wrong result:

 In: f[Rational[50, 100], Rational[4, 10]] Out: {3, 7} (* Expected: 54 / 110 -> 27 / 55 *) 

Is there any way to get Mathematica to stop simplifying the expression right away? I can just hold on to everything that I go through, then the function in question simply calls ReleaseHold [..] on everything that has been transferred.

This solution is very ugly, and I do not want to do this. I know that some functions in Mathematica automatically hold everything that is transferred and delay it for some reason, and I would like to do it here.

In short: How can I get Mathematica to lazily evaluate something passed to a function without having to manually hold it?

+4
source share
2 answers

In the standard evaluation procedure, each function argument is evaluated one at a time. This can be prevented by setting the HoldFirst, HoldRest, and HoldAll attributes. These attributes make Mathematica "hold" specific arguments in an invaluable way.

http://reference.wolfram.com/legacy/v5/TheMathematicaBook/PrinciplesOfMathematica/EvaluationOfExpressions/2.6.5.html

eg.

The docs say that any auto-content arguments are automatically evaluated when they are first used in the function body. However, if for some reason you want to continue working with an argument in the form of "Hold" (for example, if you want to match and rewrite templates in an unvalued form of expression), then maybe you can Hold it again.

+5
source

Using the HoldAll attribute mentioned by ninjagecko, I was able to create a solution.

In fact, there was another problem that I could not immediately see. In particular, my function was not pattern matching, as I thought it would be.

I thought my initial question was simply that Mathematica automatically simplified my expressions, and I needed to lazily evaluate the parameters passed for the correct behavior.

In fact, I forgot that there are several ways to represent expressions in Mathematica. As an example of toys, consider the following function, which extracts the numerator and denominator of a fraction:

 ExtractNumDem[Fraction[a_, b_]] := {a, b} (* Already incorrect, ExtractNumDem[4 / 100] gives {1, 25} *) 

Just adding the HoldAll attribute (or HoldFirst even) leads to another problem:

 SetAttributess[ExtractNumDem, HoldAll]; ExtractNumDem[4 / 100] (* Gives ExtractNumDem[4 / 100] *) 

The 4/100 expression actually evaluates Times[4, Power[100, -1]] . To fix this second problem, I had to add a definition for fractions that look like this:

 ExtractNumDem[Times[a_, Power[b_, -1]] := {a, b} ExtractNumDem[4/100] (* Now gives {4, 100} *) 

My solution to the problem in my original answer applied the same exact principle. Here is some code to see the problem I encountered:

 ClearAll[ExtractNumDem] ExtractNumDem[Rational[a_, b_]] := {a, b} ExtractNumDem[4 / 100] SetAttributes[ExtractNumDem, HoldAll]; ExtractNumDem[4 / 100] ExtractNumDem[Times[a_, Power[b_, -1]]] := {a, b} ExtractNumDem[4/100] 
+1
source

All Articles