1
$\begingroup$

I'm not sure if this problem has been asked before as I don't know the keyword to search for it.
I have a function where return result contains variable b (just for illustration).

myfunction[a_] := Module[{},
  1 + (2 a - 1) b ]

I want it to always return an expression with b unevaluated and only evaluate it when I do some replacement.

enter image description here

enter image description here

This one works as b is not used anywhere (not being assigned some value).
However, now assume that b is assigned somewhere then the function below is evalued with that b.

enter image description here

And in the result below with replacment the result is 4 instead of 2 as what I want.

enter image description here

$\endgroup$
4
  • 5
    $\begingroup$ You are trying to subvert a pretty fundamental part of the language. Try to describe the problem you are trying to solve, rather than the solution you are attempting to implement. I suspect there might be another way to achieve your original goal. $\endgroup$
    – MarcoB
    Commented Apr 9, 2022 at 14:25
  • $\begingroup$ One workaround would be to use Clear[b] just before you call myfunction. Or to add Clear[b] into the function: myfunction[a_] := Module[{}, Clear[b]; 1 + (2 a - 1) b]. $\endgroup$
    – bill s
    Commented Apr 9, 2022 at 15:26
  • $\begingroup$ @MarcoB I want to have a function that retun an expression with variables that I can replace later to get the value if needed. If I make b local then I cannot return b but something like $1000 and it's hard to replace for value later. ut $\endgroup$
    – hana
    Commented Apr 9, 2022 at 16:24
  • $\begingroup$ @bills I did that too but I wondered if there is a better way as I used too many variables so I'm kind of lacking names. $\endgroup$
    – hana
    Commented Apr 9, 2022 at 16:25

3 Answers 3

4
$\begingroup$

Why not define your function with two input variables?

myfunction[a_, b_] := Module[{}, 1 + (2 a - 1) b ]

That way you can assignments like, enter image description here

Although it's a bit more complex if you want a two-variable function to assign one variable with the second deferred you could also use the CurryApplied function. This is a common feature in functional programming languages like Haskell. So you can define:

myFunctionB = CurryApplied[myFunction, 2][x];

which will assign x to the variable a in myFunction. And then at a later time, you can assign the variable b to myFunctionB:

myFunctionB[y]

which will return

1 + (-1 + 2 x) y
$\endgroup$
3
$\begingroup$

If it is acceptable for you to return b in the function as a string instead of as a variable you could do the following:

f[a_]:=Module[{},  1 + (2 a - 1) "b" ]

Then you could just replace "b" instead of b:

f[1]/."b"->2
$\endgroup$
3
$\begingroup$

Here's something you could do:

myfunction[a_] := Block[{b},  HoldForm[Evaluate[1 + (2 a - 1) b]]]

b = 2;
ReleaseHold[myfunction[1] /. Unevaluated[b -> 1]]

I don't recommend this style of programming, though. It's easy to mess up the holding/releasing of evaluations and get a wrong result. If you need variables that are supposed to not have values assigned to them, I recommend using Formal symbols instead, such as:

http://reference.wolfram.com/language/ref/character/FormalB.html

Edit

Another strategy for the last line would be:

Block[{b = 1}, ReleaseHold[myfunction[1]]]
$\endgroup$

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.