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