MathGroup Archive 2011

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Delayed symbol resolution

  • To: mathgroup at smc.vnet.net
  • Subject: [mg122724] Re: Delayed symbol resolution
  • From: "Oleksandr Rasputinov" <oleksandr_rasputinov at hmamail.com>
  • Date: Mon, 7 Nov 2011 05:54:55 -0500 (EST)
  • Delivered-to: l-mathgroup@mail-archive0.wolfram.com
  • References: <j95p5g$m5l$1@smc.vnet.net>

On Sun, 06 Nov 2011 10:56:48 -0000, Rui <rui.rojo at gmail.com> wrote:

> A few scattered times in my not too long Mathematica history I've found  
> myself facing a similar simple problem that always required particular  
> attention to solve it.
> The problem, in broad terms: needing to insert a symbol whose context is  
> the current context at the time the code is being evaluated. Of course,  
> this might mean the symbol could be used as an argument to a HoldAll  
> function that receives a Symbol, so it can't be evaluated. So I end up  
> using MakeExpression or ToExpression wrapping the result in Hold and  
> then doing some (to me) hard expression manipulation with Applies,  
> RemoveHolds and Replaces which results in a code that might work but is  
> far from neat and understandable. I might add, the heavy expression  
> manipulation and Holds and replacements and etc were never my strong  
> suit...
>
> So finally I'm doing what I should have done from the start:
> * Ask here if there's a simple way to solve it
> * Create a short function in a package.
>
> I'll do the second one right now, and if you make me realise it's  
> redundant I'll throw it away. If not, I'll share it.
>
> I'm thinking of something Block-like such as
> WithDelayedSymbols[{x, y}, (* code using x and  y*)]
> where every appearance of x and y would be replaced by the current  
> context symbols of ToExpression[x] and ToExpression[y] prior to any  
> evaluation.
> Also, a
> BlockDelayedSymbols[{x, y}, ...] which also adds dynamic scoping like  
> Block
>
> Rui Rojo
>

I'm not sure that I can suggest any general solutions to your problem, so  
I will just comment here that I make heavy use of With and rarely come  
across these sorts of issues. (For function arguments, Evaluate is often  
more appropriate than With.) In the (in my experience, rare) cases for  
which With is not sufficient, and where a pattern can be found to refer to  
the important parts of the expression, you can use the following approach  
combining With and either ReplaceAll or ReplaceRepeated (that I learned of  
 from Ted Ersek, but which he states was invented by Michael Trott and Adam  
Strzebonski). This has been mentioned several times already by other  
posters, but I thought it would be useful to provide a little extra  
functionality via options:

EvaluatePattern[expr_, patt_, opts___] :=
  Module[{holdTemporary},
   If[TrueQ[Hold /. {opts} /. Options[EvaluatePattern, Hold]],
    SetAttributes[holdTemporary, HoldAll]
   ];
   Identity @@ ReplaceRepeated[
     holdTemporary[expr],
     p : patt :> With[{eval = p}, eval /; True],
     MaxIterations -> (
       MaxIterations /. {opts} /.
        Options[EvaluatePattern, MaxIterations]
      )
    ]
  ];
Attributes[EvaluatePattern] = {HoldFirst};
Options[EvaluatePattern] = {
   MaxIterations -> $IterationLimit, Hold -> False
  };

As a usage example, we could try inlining nested functions. This might be  
useful as a preprocessing step for Compile, as the CompilationOptions  
setting "InlineExternalDefinitions" doesn't deal with nested definitions:

In[5] :=
f=Function[{x},x];
g=Function[{y},f[y]];
h=Function[{z},g@f[z]];
k=Function[{w},h@g@f[w]];

In[9] :=
SetSystemOptions["CompileOptions"->"CompileReportExternal"->True];

In[10] :=
Compile[{u},k[u],CompilationOptions->"InlineExternalDefinitions"->True]

During evaluation of In[10] :=
Compile::extscalar: h[g[f[Compile`FunctionVariable$244]]] cannot be  
compiled and will be evaluated externally. The result is assumed to be of  
type Integer. >>

Out[10] =
CompiledFunction[{u},Function[{w},h[g[f[w]]]][u],-CompiledCode-]

In[11] :=
EvaluatePattern[
  Compile[{u},k[u]],
  sym_Symbol/;Head[sym]===Function,
  Hold->True
]

Out[11]=
CompiledFunction[{u},Function[{w},Function[{z},Function[{y},Function[{x},x][y]][Function[{x},x][z]]][Function[{y},Function[{x},x][y]][Function[{x},x][w]]]][u],-CompiledCode-]

Although the second CompiledFunction looks more complicated, if you look  
at the compiled code you will see that in fact the expression optimizer  
has removed all of the function calls and reduced it to a series of  
assignments that end up simply returning the argument.



  • Prev by Date: Re: Constraint evaluation in NMinimize
  • Next by Date: Re: nVidia Optumus prevents using CUDA?
  • Previous by thread: Delayed symbol resolution
  • Next by thread: Re: Delayed symbol resolution