Leaving values ​​for options not rated by Mathematica

I am having trouble writing a function that takes parameters. One of the parameter values ​​is a function. I have to get this value, but do not value it. I tried everything that I could think of, but so far nothing worked.

Basically, to illustrate this, I tried:

SetAttributes[Foo, HoldRest]; Options[Foo] = {Blah -> None} Foo[x_, OptionsPattern[]] := Module[{blah}, blah = OptionValue[Automatic, Automatic, Blah, Hold]; . . . 

Then when I have:

 func[a_, b_, c_] := a + b + c; 

I would like to call Foo with:

 Foo[2, Blah -> func[1, 2, 3]] 

And let the "blah" variable (inside Foo) not be evaluated, i.e. blah = func [1, 2, 3].

Thanks for the help!

Edit:

For reasons that are too long for development, I cannot use RuleDelayed (:>). I am trying to write a function that will be in a package used by other people who really do not know Mathematica, so they do not have a clue what:> there is. Using rules (->) to specify options and their values ​​is the standard way, and they are familiar with it.

So, to illustrate again, let's say I'm trying to write a number generator function that takes a function that generates an actual number as one of its options:

 Options[GenerateNumbers] = {GeneratorFunction -> None}; GenerateNumbers[n_, OptionsPattern[]] := Module[{func}, func = OptionValue[GeneratorFunction]; Table[func, {n}] ] ] 

Now, if I call this function with values ​​as follows:

 GenerateNumbers[5, GeneratorFunction -> RandomReal[10]] 

It will return a list of 5 numbers that are the same, since RandomReal [10] is evaluated once, and not at each iteration of the table. I want to prevent this. The problem is more complicated, but it is in this respect.

Thanks!

+4
source share
3 answers

Use the name for OptionsPattern , and then wrap the captured sequence object with List and Unevaluated . Very minimal way to capture the right side for Blah :

 SetAttributes[Foo, HoldRest]; Options[Foo] = {Blah -> None}; Foo[x_, opts : OptionsPattern[]] := Module[{blah}, blah = OptionValue[Foo, Unevaluated[{opts}], Blah, Hold]; blah] 

Testing:

 In[2]:= Foo[x, Blah -> (1 + 1)] Out[2]= Hold[1 + 1] 
+5
source

Why aren't you using RuleDelayed?

 Foo[2, Blah :> func[1, 2, 3]] 

In this case, blah=Hold[func[1, 2, 3]] , as expected.

+4
source

Your use of the parameters is a bit strange. If you want to convey some expression enclosed in Hold, why not wrap it in Hold when transferring, for example Blah->Hold[func[1,2,3]] ? Anyway, assuming this is a simple definition for Foo :

 Foo[x_, OptionsPattern[]] := Module[{blah}, blah = OptionValue[Automatic, Automatic, Blah, Hold]; blah ], 

you can accomplish what you want by passing an option with RuleDelayed rather than Rule :

 In[7]:= func[a_, b_, c_] := a + b + c; In[8]:= Foo[2, Blah :> func[1, 2, 3]] Out[8]= Hold[func[1, 2, 3]] 

NTN

Edit:

If you don't want to wrap Hold , here is one way to get rid of it:

 In[25]:= ClearAll[setDelayedHeld]; SetAttributes[setDelayedHeld, HoldFirst]; setDelayedHeld[lhs_, Hold[rhs_]] := lhs := rhs In[28]:= Clear[Foo]; Foo[x_, OptionsPattern[]] := Module[{blah}, setDelayedHeld[blah, OptionValue[Automatic, Automatic, Blah, Hold]]; OwnValues[blah]] In[30]:= Foo[2, Blah :> func[1, 2, 3]] Out[30]= {HoldPattern[blah$1018] :> func[1, 2, 3]} 

I am returning OwnValues to blah to show that it was assigned func[1,2,3] without evaluating the latter - if that is what you want.

+3
source

Source: https://habr.com/ru/post/1340252/


All Articles