[Date Index]
[Thread Index]
[Author Index]
RE: Re: Functional Expression Meaning (was:A Functional Expression Trick)
*To*: mathgroup at smc.vnet.net
*Subject*: [mg24016] RE: [mg23926] Re: Functional Expression Meaning (was:[mg23859] A Functional Expression Trick)
*From*: hwolf at debis.com
*Date*: Tue, 20 Jun 2000 03:07:32 -0400 (EDT)
*Sender*: owner-wri-mathgroup at wolfram.com
-----Original Message-----
From: Allan Hayes [SMTP:hay at haystack.demon.co.uk]
To: mathgroup at smc.vnet.net
Sent: Friday, June 16, 2000 6:57 AM
To: mathgroup at smc.vnet.net
Subject: [mg23926] Re: Functional Expression Meaning (was:[mg23859] A
Functional Expression Trick)
Dear David and Hartmut,
I have come across some problems with Hartmut's solution, toFunc, as written
up by David.
I offer new version, toFunc2
Hartmut's solution is
toFunc::usage =
"toFunc[expr] will convert an expression of pure functions into a pure
function.";
toFunc[expr_] := Module[{e}, Off[Pattern::patv];
Off[Function::flpar];
e = ReleaseHold[
Evaluate[
expr /. {Function[({var__} | var_), body_] :>
Block[{var},
Hold[body] /.
Thread[Rule[{var}, Array[Slot, {Length[{var}]}]]]],
Function -> Hold}] &];
On[Pattern::patv];
On[Function::flpar];
e]
I am always wary when replacement reaches inside scoping constructs
like Function, With ...., because it does not respect the scoping.
With toFunc we get
toFunc[Function[x, With[{x = 5}, a + x^2]]]
With[{#1 = 5}, a + #1\^2] &\)
Also, constant functiions give trouble:
toFunc[Function[{}, a + x]]
Block::"lvsym": "Local variable specification \!\({\({}\)}\)
contains \
\!\({}\) which is not a symbol or an assignment to a symbol."
Block[{{}},
a + x /.\[InvisibleSpace]Thread[{{}} -> Array[Slot,
{Length[{{}}]}]]] &
Func2, below, uses the functions themselves to introduce the slots, rather
than replacement. It also avoids generating messages.
toFunc2[expr_] :=
ReleaseHold[Function @@ ({expr} /.
(F_ /; F === Function)[vars_, body_] :>
Apply[F[vars, Hold[body]],
Slot /@ Range[Last[Dimensions[Unevaluated[{vars}]]]]]
)]
With this we get
toFunc2[Function[x, With[{x = 5}, a + x^2]]]
With[{x = 5}, a + x^2] &
toFunc2[Function[{}, a + x]]
a + x &
------- cut here -------
>>>>>>>
Dear Allan, dear David,
this is one of the threads so enjoyable when discussing, yet not so pleasing
(for me) at the archive.
So, Allan, thank you very much for pointing out the errors. After that, I
now come up with a surprisingly simple solution
toFunc[expr_] := expr /. f : Function[__] :> f[##] &
That's it! And I'm convinced, that it is correct. Why? It is simply based on
\[eta]-conversion, namely that
Function[{vars}, f[vars]]
has to be semantically the same as f.
The problem with David's creditable idea to introduce this functional
calculus was that the bodies of the component function had to be hold while
building the resulting function, and that functions, given as
lambda-expressions should be included into the calculus.
My idea, to achieve that through \[alpha]-conversion (= the name of the
variable must not count) however was seriously flawed: The problem is not
the substitition of the variables within scoped constructs per se, but not
with Slot, which shall not appear at the lhs!
The solution above has a small procedural drawback: the substitution is
executed at application time, i.e. possibly over and over again. But this
easily can be repaired by
toFunc[expr_] :=
ReleaseHold[Evaluate[Hold[expr] /. f : Function[__] :> f[##]] &]
What has to be noted is: the execution order of the component functions is
not the same as when traversing the held expression depth first, but if I'm
not wrong, _Mathematica_ does not give any garanties for that anyhow (when
reshuffling into canonical order occurs at intermediate steps), and
certainly you should never program relying on that order (in any language).
Kind regards,
Hartmut
Prev by Date:
**Re: I wish Descending Order Result**
Next by Date:
**Re: RE:Working Precision**
Previous by thread:
**Re: Functional Expression Meaning (was:A Functional Expression Trick)**
Next by thread:
**Questions about RoxReduce**
| |