[Date Index]
[Thread Index]
[Author Index]
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**
| |