Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>As far as I know, you can not do this directly in the sense that there isn't a <code>HoldN</code> attribute. However, below there is a work-around that should be doing what you requested.</p> <hr> <h3>Proposed solution</h3> <p>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 <code>HoldAll</code>, like so:</p> <pre><code>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] </code></pre> <p>You don't have to expose the <code>faux</code> to the top level, can wrap everyting in <code>Module[{faux}, your definitions]</code> instead. </p> <hr> <h3>Automation through meta-programming</h3> <p>This procedure can be automated. Here is a simplistic parser for the function signatures, to extract pattern names (note - it is indeed simplistic):</p> <pre><code>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_, ___] :&gt; tag, Verbatim[Condition][z_, _] :&gt; z, Verbatim[PatternTest][z_, _] :&gt; z }; </code></pre> <p>Using this, we can write the following custom definition operator:</p> <pre><code>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]] </code></pre> <p>This will analyze your original definition, extract pattern names, wrap the argument of interest in <code>Unevaluated</code>, introduce local <code>faux</code>, and make a 2-step definition - basically the steps we did manually. We need <code>SetDelayed @@ ..</code> to fool the variable renaming mechanism of <code>With</code>, so that it won't rename our pattern variables on the l.h.s. Example:</p> <pre><code>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] </code></pre> <hr> <h3>Notes</h3> <p>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 <code>Module</code>-generated auxiliary functions <code>faux</code> won't be garbage-collected when you <code>Clear</code> or <code>Remove</code> the main ones - you may need to introduce a special destructor for your functions generated with <code>defHoldN</code>. For an alternative take on this problem, see my post in <a href="http://groups.google.com/group/comp.soft-sys.math.mathematica/browse_thread/thread/81da38250f225b95" rel="noreferrer">this</a> thread (the one where I introduced the <code>makeHoldN</code> function).</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload