Anonymus functions revisited : tuple actions
Kay Schluehr
kay.schluehr at gmx.net
Thu Mar 24 04:58:48 EST 2005
Ron wrote:
> On Wed, 23 Mar 2005 06:21:30 +0100, Kay Schluehr <kayschluehr at gmx.de>
> wrote:
>
> >I think my proposal was more in mind of Rons modified exec than
> >Pythons lambda.
> >
> >When George proposed his unpacking behavoir for list-comps as a pack
of
> >suggar:
> >
> >1. [x*y-z for (x,y,z=0) in (1,2,3), (4,5), (6,7,8)]
> >
> >I interpreted it in a subsequent posting in lambda fashion:
> >
> >2. [(lambda x,y,z=0:x*y-z)(*v) for v in (1,2,3), (4,5), (6,7,8)]
>
> Thank you Kay, All of this is really intersting and I'm learning a
> lot about the language through these discussions.
Thanks, Ron !
> The following is an experiment I did this morning. :-)
>
> I was surprised it worked as well as it did, although I don't think
it
> should be used in any real production code. Not in it's present form
> anyway.
>
> The idea is to have a container class like a tuple for program code
> that can be moved around and used when needed. Very flexable, maybe
> if it could be done without the strings and the exec/eval() functions
> in it?
I personally don't like using exec and eval for stuff different from
evaluating user input.
You rely much on "evaluate statement on the line" by adapting
conventional Python syntax. I think one can go a bit further breaking
the syntactical prejudices and apply tuple-actions :)
Playing a bit with tuple-actions shows that the concept is quite
powerfull and can be used to create simple statements.
First of all the semantics has to be patched:
We have
(x,y,z=0) -> (x,y,z)
as a tuple assignment
((x,y,z=0)->(x,y,z))(a,b,c) = (x=a,y=b,z=c)
But it is not clear what
(x,y,z=0) -> x*y-z
actually means?
Proposal:
(x,y=0) -> x*y => ((x,y=0)->x*y) (a,b) -> (x=a,y=b),a*b
(x,y=0) -> (x*y) => ((x,y=0)->(x*y))(a,b) -> (x=a*b,y=b)
So (x,y=0) -> x*y is appending the result to the argument tuple.
Remark: this is isomorph to
(x,y=0,res=None) -> ((x,y),x*y)
but it becomes harder now to identify
(x,y,res=None) -> ((x,y),x*y)
with
x*y
Provide a compiler-hint:
(x,y,()) -> x*y
Now we are ready for a few examples:
default value:
(i) -> (0) # i = 0
inplace increment:
(i) -> i+1 # i = i+1
conditional expression:
(i) -> i<3 # i,res = i,i<3
simple transformation:
(res) -> (res+i**2) # res = res+i**2
Define a While loop as a function:
def While( par, cond, change, action):
par(None) # create default
res = 0
while cond(par)[1]:
action(res)
change(par)
return res
Let's apply it to some tuple actions:
While((i)->(0), (i)->i<3, (i)->(i+1), (res)->(res+i**2))
and evaluate While stepwise:
1. par(None) <=> (i)->(0)(None) # (i) = (0)
2. cond(par)[1] <=> (i)->i<3(0) # (i,c) = (0,True)
3. action(res) <=> (res) -> (res+i**2)(0) # (res) = (0)
4. change(par) <=> (i)->(i+1)(0) # (i) = (1)
5. cond(par)[1] <=> (i)->i<3(1) # (1,c) = (0,True)
6. action(res) <=> (res) -> (res+i**2)(0) # (res) = (1)
7. change(par) <=> (i)->(i+1)(1) # (i) = (2)
5. cond(par)[1] <=> (i)->i<3(2) # (2,c) = (0,True)
6. action(res) <=> (res) -> (res+i**2)(1) # (res) = (5)
7. change(par) <=> (i)->(i+1)(2) # (i) = (3)
5. cond(par)[1] <=> (i)->i<3(2) # (2,c) = (0,False)
break
=> res = 5
If we customize the other control flow primitives For and If it should
be possible to create a little language only by using this primitives.
It is obvious by definition of our While that we can replace arguments
on the fly:
conds = [(i)->i<3, (i)->i+2<7, (i)->i>=0]
[ While((i)->(0), cond, (i)->(i+1), (res)->(res+i**2)) for cond in
conds]
=> [5,29,0]
Wouldn't it be fun to use in Python?
Only drawback: does not look like executable pseudo-code anymore :(
Regards Kay
More information about the Python-list
mailing list