Mathematica provides many functions which are capable of handling Dynamic as an argument.
For example, the function FileNameSetter has the following variant:
FileNameSetter[Dynamic[name]]
uses the dynamically updated current value of name, with the
value of name being reset if a different file is chosen.
I wonder how one goes about defining a function pattern that takes a dynamic expression as an argument. For example, here is one attempt to wrap the dynamic variant of the function LocatorPane:
SinLocatorPane[Dynamic[sinvalue_]] :=
LocatorPane[Dynamic[x, (x = #; sinvalue = Sin[First[#]]) &],
Plot[Sin[x], {x, 0, 10}]]
What is the correct pattern to use for a dynamic expression argument? Are there any caveats with using the dynamic argument inside the function definition?
If you would like to write a function that updates the value of a certain variable, this is like passing a variable by reference. Standard way of achieving this in Mathematica is to use Hold* attributes on your function.
SetAttributes[SinLocatorPane, HoldFirst];
SinLocatorPane[sinvalue_] :=
LocatorPane[Dynamic[x, (x = #; sinvalue = Sin[First[#]]) &],
Plot[Sin[x], {x, 0, 10}]]
Then
{Dynamic[sv], SinLocatorPane[sv]}
would work as your expected. Your code worked because Dynamic has HoldFirst attributed and this allowed your code to update variable sinvalue. Otherwise Dynamic was not really needed
Related
For example, the following rule to create a slider that edits a given variable:
EditorLine[stat_] := {
Labeled[Slider[Dynamic[stat], {1, 20, 1}],
{SymbolName[Unevaluated[stat]]}, {Left}], Dynamic[stat]}
SetAttributes[EditorLine, HoldFirst]
This works fine for EditorLine[x], but using a map - e.g., EditorLine /# {x,y,z}, gives an error because the map function evaluates the variable names and thus they are not held.
This can be done by writing EditorLine /# {Unevaluated[x],Unevaluated[y],Unevaluated[z]} but if I wanted to write repeated function calls like that I would not be using a map!
Is there any better way of doing this?
This will work too:
EditorLine /# Unevaluated[{x, y, z}]
and if you add Listable attribute, even shorter:
EditorLine[{x, y, z}]
Is it possible to define a function that holds arguments at given positions ?
Or to do something like HoldLast as a counterpart to HoldFirst ?
As far as I know, you can not do this directly in the sense that there isn't a HoldN attribute.
However, below there is a work-around that should be doing what you requested.
Proposed solution
One simple way is to define an auxiliary function that will do the main work, and your "main" function (the one that will actually be called) as HoldAll, like so:
In[437]:=
SetAttributes[f, HoldAll];
f[a_, b_, c_] :=
faux[a, Unevaluated[b], c];
faux[a_, b_, c_] := Hold[a, b, c]
In[440]:= f[1^2, 2^2, 3^2]
Out[440]= Hold[1, 2^2, 9]
You don't have to expose the faux to the top level, can wrap everyting in Module[{faux}, your definitions] instead.
Automation through meta-programming
This procedure can be automated. Here is a simplistic parser for the function signatures, to extract pattern names (note - it is indeed simplistic):
splitHeldSequence[Hold[seq___], f_: Hold] := List ## Map[f, Hold[seq]];
getFunArguments[Verbatim[HoldPattern][Verbatim[Condition][f_[args___], test_]]] :=
getFunArguments[HoldPattern[f[args]]];
getFunArguments[Verbatim[HoldPattern][f_[args___]]] :=
FunArguments[FName[f], FArgs ## splitHeldSequence[Hold[args]]];
(*This is a simplistic "parser".It may miss some less trivial cases*)
getArgumentNames[args__FArgs] :=
args //. {
Verbatim[Pattern][tag_, ___] :> tag,
Verbatim[Condition][z_, _] :> z,
Verbatim[PatternTest][z_, _] :> z
};
Using this, we can write the following custom definition operator:
ClearAll[defHoldN];
SetAttributes[defHoldN, HoldFirst];
defHoldN[SetDelayed[f_[args___], rhs_], n_Integer] :=
Module[{faux},
SetAttributes[f, HoldAll];
With[{heldArgs =
MapAt[
Unevaluated,
Join ## getArgumentNames[getFunArguments[HoldPattern[f[args]]][[2]]],
n]
},
SetDelayed ## Hold[f[args], faux ## heldArgs];
faux[args] := rhs]]
This will analyze your original definition, extract pattern names, wrap the argument of interest in Unevaluated, introduce local faux, and make a 2-step definition - basically the steps we did manually. We need SetDelayed ## .. to fool the variable renaming mechanism of With, so that it won't rename our pattern variables on the l.h.s. Example:
In[462]:=
ClearAll[ff];
defHoldN[ff[x_,y_,z_]:=Hold[x,y,z],2]
In[464]:= ?ff
Global`ff
Attributes[ff]={HoldAll}
ff[x_,y_,z_]:=faux$19106##Hold[x,Unevaluated[y],z]
In[465]:= ff[1^2,2^2,3^2]
Out[465]= Hold[1,2^2,9]
Notes
Note that this is trivial to generalize to a list of positions in which you need to hold the arguments. In general, you'd need a better pattern parser, but the simple one above may be a good start. Note also that there will be a bit of run-time overhead induced with this construction, and also that the Module-generated auxiliary functions faux won't be garbage-collected when you Clear or Remove the main ones - you may need to introduce a special destructor for your functions generated with defHoldN. For an alternative take on this problem, see my post in this thread (the one where I introduced the makeHoldN function).
Another way to do would be for example:
SetAttributes[f,HoldFirst];
f[{heldArg1_,heldArg2_},arg3_,arg4_,arg5_]:= Hold[arg3 heldArg1];
And this would allow to be able to have any mix of held and non held arguments.
HoldRest could be used similarly.
As noted elsewhere, you can list all user-defined symbols with this:
Names["Global`*"]
But I'd like to find just my global variables (I'm in the middle of some hairy debugging), not my function definitions. Something like this is close:
Select[Names["Global`*"], Head#Symbol[#]=!=Symbol && Head#Symbol[#]=!=Function&]
But that misses variables whose value is a symbol (perhaps I have x = Pi).
I could probably beat that thing into submission but maybe there's a cleaner, more direct way?
If we consider any symbol with an own-value as a "variable", then this will do the trick:
ClearAll[variableQ]
variableQ[name_String] := {} =!= ToExpression[name, InputForm, OwnValues]
Select[Names["Global`*"], variableQ]
Note that this technique will fail on read-protected symbols and will misidentify some forms of auto-loaded functions.
Edit 1
As #Szabolcs points out, the definition of variableQ can be simplified if ValueQ is used:
variableQ[name_String] := ToExpression[name, InputForm, ValueQ]
Edit 2
As #dreeves points out, it might be desirable to filter out apparent variables whose values are functions, e.g. f = (#+1)&:
variableQ[name_String] :=
MatchQ[
ToExpression[name, InputForm, OwnValues]
, Except[{} | {_ :> (Function|CompiledFunction)[___]}]
]
This definition could be easily extended to check for other function-like forms such as interpolating functions, auto-loaded symbols, etc.
One might consider a variable to be a Global` symbol that does not pass FunctionQ.
I want to define a symbol and use it within a function. For example, with IDnumbers defined as a list of numbers:
ParallelMap[{#1, Name[#1], Age[#1]} &, IDnumbers]
With userlist={#1, Name[#1], Age[#1]} becomes:
ParallelMap[userlist &, IDnumbers]
It works just fine with the list itself in the code, but not with the symbol. The same thing happens with a list of strings vs. a symbol assigned to a list of strings. Why is this?
Since f[#]& is shorthand for Function[f[#]] you should always complete your anonymous function with a trailing & to get a working function.
In your example:
userlist={#1, Name[#1], Age[#1]}&
ParallelMap[userlist, IDnumbers]
More thorough explanation:
By just using something like f[#] you get (in FullForm[])
In[15] := f[#] // FullForm
Out[15]//FullForm = f[Slot[1]]
whereas this gets transformed to a Function by the trailing & operator:
In[16] := f[#]& // FullForm
Out[16]//FullForm = Function[f[Slot[1]]]
If you do this in two steps, & doesn't evaluate the intermediate variable expr:
In[25]:= expr = f[#]//FullForm
In[26]:= expr &
Out[25]//FullForm = f[Slot[1]]
Out[26] = expr &
You can force the evaluation of expr before it gets wrapped in the Function[] by using Evaluate[]:
In[27]:= expr=f[#]//FullForm
In[28]:= Evaluate[expr]&
Out[27]//FullForm = f[Slot[1]]
Out[28] = f[Slot[1]]&
Another way is to supply the Function[] wrapper yourself:
userlist={#1, Name[#1], Age[#1]}
ParallelMap[Function[userlist], IDnumbers]
Personally, i would consider this bad coding style. Just get used to always finishing an anonymous function with a trailing & like you would supply a closing paranthesis ) to a corresponding opening one (.
Edit
Ok, in your case of a dynamically generated anonymous function i can see why you couldn't supply the & directly. Just wrap the expression with the Slot[]s in a Function[] instead.
Is it possible to use Mathematica's manipulate to change variables that have already been declared?
Example:
changeme = 8;
p = SomeSortOfPlot[changeme];
manipulate[Show[p],{changeme,1,10}]
The basic idea is that I want to make a plot with a certain changable value but declare it outside of manipulate.
Any ideas?
One option is to use Dynamic[] and LocalizeVariables -> False.
Example:
changeme = 8;
p[x_] := Plot[Sin[t], {t, 1, x}];
{
Manipulate[p[changeme], {changeme, 2, 9}, LocalizeVariables -> False],
Dynamic[changeme] (* This line is NOT needed, inserted just to see the value *)
}
Evaluating "changeme" after the Manipulate action will retain the last Manipulate value.
HTH!
If you want anything reasonably complicated or flexible, it is best to use Dynamic and DynamicModule instead of Manipulate. The only exception is if you're writing a demonstration.
For example - a very basic way of doing what you want is
(in fact you don't even need the Row and Slider if you want to just change changeme by hand.)
changeme=8;
p[x_]:=Plot[Sin[t],{t,1,x}];
Row[{"x \[Element] (1, ",Dynamic[changeme],") ",Slider[Dynamic[changeme],{2,9}]}]
Dynamic[p[changeme]]