Re: Re: Add syntax highlighting to own command
- To: mathgroup at smc.vnet.net
- Subject: [mg101871] Re: [mg101832] Re: Add syntax highlighting to own command
- From: Leonid Shifrin <lshifr at gmail.com>
- Date: Mon, 20 Jul 2009 06:01:49 -0400 (EDT)
- References: <200907090600.CAA17547@smc.vnet.net> <h3766u$f9h$1@smc.vnet.net>
Hi Bastian,
If I understand you correctly and the last rule you added
( Let /: ( lhs_ := Let[ vars_, expr_ /; cond_ ] ) :=
Let[ vars, lhs := expr /; cond ])
is to allow shared local variables in function definitions (like with
standard
With, Module or Block), then your code does not work for me.
Here is your code:
In[1] =
SetAttributes[ Let, HoldAll ]
SyntaxInformation[ Let ] =
{ "ArgumentsPattern" -> { _, _ } }
Let /: ( lhs_ := Let[ vars_, expr_ /; cond_ ] ) :=
Let[ vars, lhs := expr /; cond ]
Let[ { }, expr_ ] := expr;
Let[ { head_ }, expr_ ] := With[ { head }, expr ]
Let[ { head_, tail__ }, expr_ ] :=
With[ { head }, Let[ { tail }, expr ] ]
Consider the following definition:
In[2] =
Clear[f];
f[x_, y_] := With[{xl = x}, With[{yl = y + xl + 1}, xl^2 + yl^2 /; (xl + yl
< 15)]];
f[x_, y_] := x + y;
In[3] = ?f
Out[3] =
Global`f
f[x_,y_]:=With[{xl=x},With[{yl=y+xl+1},xl^2+yl^2/;xl+yl<15]]
f[x_,y_]:=x+y
This is supposed to be equivalent to the following:
In[4] =
Clear[f];
f[x_, y_] := Let[{xl = x, yl = y + xl + 1}, xl^2 + yl^2 /; (xl + yl <
15)];
f[x_, y_] := x + y;
But it is not:
In[5] = ?f
Out[5] =
Global`f
f[x_,y_]:=x+y
I can think of several reasons why this does not work, and will expand this
discussion if you will be interested, but here is the version that I
believe does work:
In[6] =
ClearAll[Let];
SetAttributes[Let, HoldAll];
Let /:
Verbatim[SetDelayed][lhs_, rhs : HoldPattern[Let[{__}, _]]] :=
Block[{With},
Attributes[With] = {HoldAll};
lhs := Evaluate[rhs]];
Let[{}, expr_] := expr;
Let[{head_}, expr_] := With[{head}, expr];
Let[{head_, tail__}, expr_] :=
Block[{With},
Attributes[With] = {HoldAll};
With[{head}, Evaluate[Let[{tail}, expr]]]];
This uses the Block trick. It is actually a true macro, since
it expands the code before SetDelayed acts on it:
In[7] =
Clear[f];
f[x_, y_] := Let[{xl = x, yl = y + xl + 1}, (Print["*"]; xl^2 + yl^2) /;
(xl + yl < 15)];
f[x_, y_] := x + y;
In[8] = ?f
Out[8] =
Global`f
f[x_,y_]:=With[{xl=x},With[{yl=y+xl+1},(Print[*];xl^2+yl^2)/;xl+yl<15]]
f[x_,y_]:=x+y
In[9] = f[1,2]
*
Out[9] = 17
In[10] = f[1,20]
Out[10] = 21
Regards,
Leonid
On Sat, Jul 18, 2009 at 5:00 AM, Bastian Erdnuess <earthnut at web.de> wrote:
> rych <rychphd at gmail.com> wrote:
>
> > On Jul 16, 1:19 pm, earth... at web.de (Bastian Erdnuess) wrote:
> > > Bastian Erdnuess <earth... at web.de> wrote:
> >
> > >
> > > Let /: ( lhs_ := Let[ vars_, expr_ /; cond_ ] ) :=
> > > Let[ vars, lhs := expr /; cond ]
> > >
> >
> >
> > I'm sorry, Bastian, but can I ask you what you're trying to achieve
> > with these lines? Actually, I've never seen more than one SetDelayed
> > in an expression.
>
> In the help for With is written
>
> - You can use With[ { vars }, body /; cond ] as the right-hand side
> of a transformation rule with a condition attached.
>
> I tried to get the same behaviour to the Let construct.
>
> I found out one can write the upper rule also straight as
>
> ( lhs_ := Let[ vars_, expr_ /; cond_ ] ) ^:=
> Let[ vars, lhs := expr /; cond ]
>
> as an UpRule.
>
> > When I try to test this definition as follows, I get
> > a "SetDelayed::shape" error,
> >
> > {x, y, z, w} := Let[{a = 1, b = a + 1, c = b + 1, d = a + b + c}=
> > , {a,
> > b, c, d}]
>
> I don't see what you try to do. This shouldn't match any of the rules
> for Let at all. I get the same error, also when I use a symbol like Foo
> instead of Let which has no rules attached.
>
> Bastian
>
>
- References:
- Add syntax highlighting to own command
- From: earthnut@web.de (Bastian Erdnuess)
- Add syntax highlighting to own command