Anonymus functions revisited

K

Kay Schluehr

Since George Sakkis proposed a new way of doing list comprehensions

http://groups-beta.google.com/group...3ad18b2835f/d3ff1b81fa70c8a7#d3ff1b81fa70c8a7

letting tuples-like objects (x,y,z=0) acting as functions on other
tuples I wonder why this would not be a good starting point of
rethinking anonymus functions?

In Georges proposition the action is

(x,y,z=0) -> (x,y,z)

i.e. mapping tuples on other tuples. This is equivalent to

lambda x,y,z=0:(x,y,z)

But regarding tuples as actions by means of an arrow "->" would
generalize this idea:

Mappings like that:

((x,y),z) -> x+y-z

((x,y=0),z) -> None

should be valid actions too.

What is the audience thinking about that?

Regards Kay
 
B

bruno modulix

Kay said:
Since George Sakkis proposed a new way of doing list comprehensions

http://groups-beta.google.com/group...3ad18b2835f/d3ff1b81fa70c8a7#d3ff1b81fa70c8a7

letting tuples-like objects (x,y,z=0) acting as functions on other
tuples I wonder why this would not be a good starting point of
rethinking anonymus functions?

In Georges proposition the action is

(x,y,z=0) -> (x,y,z)

i.e. mapping tuples on other tuples. This is equivalent to

lambda x,y,z=0:(x,y,z)

But regarding tuples as actions by means of an arrow "->" would
generalize this idea:

Mappings like that:

((x,y),z) -> x+y-z

((x,y=0),z) -> None

should be valid actions too.

What is the audience thinking about that?

IMHO, it's just lambda in disguise, and I'm not sure it's more readable
than lambda. You'll have to provide more arguments (sorry for the pun
!-) to gain my adhesion. (NB : I could use this syntax without problem,
it's just that we already have a syntax for this).
 
R

Ron

Mappings like that:

((x,y),z) -> x+y-z

((x,y=0),z) -> None

should be valid actions too.

What is the audience thinking about that?

I think that there's too much implied, and that in the long run it,
if we keep addding in special shortcuts, it will lead to very dificult
to read code.
 
D

Diez B. Roggisch

letting tuples-like objects (x,y,z=0) acting as functions on other
tuples I wonder why this would not be a good starting point of
rethinking anonymus functions?

In Georges proposition the action is

(x,y,z=0) -> (x,y,z)

i.e. mapping tuples on other tuples. This is equivalent to

lambda x,y,z=0:(x,y,z)

As you say for yourself, that's just lambda in disguise. So I guess the same
arguments about the in- or exclusion of lambda apply here. I personally
like lambda, but _can_ live without it.
 
B

bruno modulix

which is in fact not a valid solution in the context of Georges'
problem... (or I failed to get it to work !-)

IMHO, it's just lambda in disguise, and I'm not sure it's more readable
than lambda. You'll have to provide more arguments (sorry for the pun
!-) to gain my adhesion. (NB : I could use this syntax without problem,
it's just that we already have a syntax for this).

Changing my mind after a more torough re-reading of the original thread
and few tests... The original problem is about tuple unpacking. The
proposed solution solves this problem, *and* can (could ?) be a
replacement for lambdas.

hmmm... I like the idea of having a more flexible tuple unpacking with a
function-call-like semantic, but I'm still not sure to like the idea of
replacing lambda with the proposed syntax.

needs-some-more-thinking-on-this-ly'yrs
 
B

bruno modulix

Diez said:
As you say for yourself, that's just lambda in disguise.

Not exactly in fact - unless I messed something. There are 2 problems
here: a more flexible tuple unpacking, *and* a lambda in disguise.
Actually, I'd go + 1 for the first, -1 for the second
So I guess the same
arguments about the in- or exclusion of lambda apply here.

For the second part, yes. Not for the first one.
I personally
like lambda, but _can_ live without it.

Yes, one can live without...
<troll>
....and without list comprehensions, __call__ and other special methods,
descriptors, metaclasses, first class functions, builtin datatypes like
lists and dicts, exceptions, dynamic typing, garbage collection, etc
too. Hurray, let's all happily program in assembly !-)
</troll>
 
D

Diez B. Roggisch

Not exactly in fact - unless I messed something. There are 2 problems
here: a more flexible tuple unpacking, *and* a lambda in disguise.
Actually, I'd go + 1 for the first, -1 for the second

The proposed syntax from Kay is lambda in disguise. To make it work like
George want it is modifying the unpacking behaviour. Actually while Kay
proposed his syntax as result of the discussion started by George it won't
work for that case. The reason is simply that the lambda form returns a
tuple, but does not make any revelations about the variable names that
tuple shall be unpacked to.

So they are in fact unrelated - at least if introduced as declared. An
augmentation to fulfill George's wishes could look like this:

[a,b,c for a,b,c: (x,y,z=0)-> x,y,z) in values]
Yes, one can live without...
<troll>
...and without list comprehensions, __call__ and other special methods,
descriptors, metaclasses, first class functions, builtin datatypes like
lists and dicts, exceptions, dynamic typing, garbage collection, etc
too. Hurray, let's all happily program in assembly !-)
</troll>

You are right, but for lambda in its current limited form short, named
functions are a good replacement. I don't want to get rid of lambda - but
since listcomps got introduced, 95% of my usages of them disappeared.
 
R

Ron

What about a safe exec as a replacement to lamba but witht he
flexability of exec in a safe and limeted way?

safe_exec ( (*inputs) , (expressionstring) , ( *outputs) )

Functon to return a default value: return arg

Safe exec command:(1, 2, 0)

What could we do, not do with this?



* I actually started this reply here, so below is how I got to the
above exression.


I'm trying to put my finger on the basic inconsistency here. It has
something to do with the z=0 as a way to defining a default .

Then there's the lamba which I hear may be removed, but is difficult
to understand for beginners, and isn't readable in that the name
doesn't say what it does. An alternative name, and possibly a
simpler syntax would be a plus.

Another concept that this touches is the indirect execution of an
expression. Exec and eval do that, but then you introduce security
issues.

I'm wondering if there's a fundamental concept under these issues such
as a base function class or command that can evaluate the contents of
a tuple in a secure way?

value = fn(arg, returnvalue)
2

Use lists or tuples for multiple arguments and return expressions:
(1, 2, 3)

But it's that "z=0" causes problems here. In a tuple it's equivalent
to saying 1=2. or 'a'='b'

So we need a way to say 'if name is undefined, bind it to object'.

# function to give a default value
def dfv( arg = value):
return arg
(1, 2, 3)

Now since this could execute in it's own private space, it might also
offer a way to use exec or eval() indirectly in a very limited and
safe way.
"""
result = ''
data = 'abcdefghigklmnop'
for ch in data:
if ch != filterc:
result.join(ch)
"""
So we need to use a three item tuple:

safe_exec ( (*inputs) , (expressionstring) , ( *outputs) )
(1, 2, 0)

Long way around to here, but is this something that has potential?
It would have to be a built in to ensure it's safe to use. But with
an exec string, it can possibly do a lot more than lamba, and it
probably wouldn't be as fast. But the flexibility could be useful.

Ron
 
B

Bruno Desthuilliers

Ron a écrit :
(snip)
return arg
>
.... return arg
....
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'value' is not defined

And sorry, but -1 for using exec here.
 
B

Bruno Desthuilliers

Ron a écrit :
I think that there's too much implied, and that in the long run it,
if we keep addding in special shortcuts, it will lead to very dificult
to read code.
Don't like Perl ?-)

The problem here is that Kay's proposition mixes two points: flexible
tuple unpacking and a new syntax for anonymous functions.
 
B

Bruno Desthuilliers

Diez B. Roggisch a écrit :
(snip)
You are right, but for lambda in its current limited form short, named
functions are a good replacement.

-inf on this !-)
 
R

Ron

Ron a écrit :
(snip)
... return arg
...
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'value' is not defined

And sorry, but -1 for using exec here.


Yes, I cought that myself. So...

try: z=z
except: z=0

or

if 'z' not in locals():
z = 0

Ok, thinking in more incremental terms...

Why should a function not create a local varable of an argument if the
varable doesn't exist and a default value is given?

So when:

Def dfv( v=0):
return v
0 ;it creates the local copy in this case.
25 ;It used the given value as expected.
Traceback (most recent call last):
File "<pyshell#4>", line 1, in -toplevel-
dfv(b)
NameError: name 'b' is not defined

Why not let it set the local varable v to the default as it does when
no varable is specified?

A function without a default would still give an error as expected.


:)
Ok no exec, but what about the general syntax?

value = keyword (inputargs, command, outputargs)

I was thinking if it can be done with standard tuples, it has the
potential to be passed around easily and work from lists and
dictionaries.

Ron
 
R

Ron

Why should a function not create a local varable of an argument if the
varable doesn't exist and a default value is given?

ok... thought it out better. :)

Getting a default into a function isn't the problem. Returning the
value to a varable that doesn't exist is.

So then the question is ... is there a way for a function to create a
varable in it's parents namespace that persists after the function is
done?
 
G

George Sakkis

Ron said:
ok... thought it out better. :)

Getting a default into a function isn't the problem. Returning the
value to a varable that doesn't exist is.

So then the question is ... is there a way for a function to create a
varable in it's parents namespace that persists after the function is
done?

Yeap.. a simple one-liner can do the trick:

def makeVars(**nameVals):
sys._getframe(1).f_locals.update(nameVals)

try: b
except NameError: print "Before makeVars: NameError"
else: print "Before makeVars: Not NameError"
makeVars(b=2)
try: b
except NameError: print "After makeVars: NameError"
else: print "After makeVars: Not NameError"

George
 
R

Ron

Yeap.. a simple one-liner can do the trick:

def makeVars(**nameVals):
sys._getframe(1).f_locals.update(nameVals)

try: b
except NameError: print "Before makeVars: NameError"
else: print "Before makeVars: Not NameError"
makeVars(b=2)
try: b
except NameError: print "After makeVars: NameError"
else: print "After makeVars: Not NameError"

George

Cool! Thanks George, so I can do this:

# Set a varable to a default value if it doesn't exist.
# Return the same value back if it does.
# Use: varable = dfvalue( varable=object)
def defvalue(**var):
if var.keys()[0] not in sys._getframe(1).f_locals.keys():
return var.values()[0]
return sys._getframe(1).f_locals[var.keys()[0]]

f = defvalue(f=0)
print f # 0

g = 19
g = defvalue(g=0)
print g # 19


Would there be any problems with using this function?

Not sure where I need it. Was thinking it could be used inside
expressions somehow, and it was an iteresting problem. ;)

Ron
 
R

Ron

Ron a écrit :
Don't like Perl ?-)

I tried it.. Wrote a html reformatter in it a long time ago. Wasn't
tempted to do anything else with it. It was good for that, but I went
a month later and had trouble figuring out how it worked. :)
The problem here is that Kay's proposition mixes two points: flexible
tuple unpacking and a new syntax for anonymous functions.

Yes, two different problems. I don't think anything needs to be done
to tuples myself. I tend to use lists more anyway.


As far as anonymous functions go... What if there where a container
type to hold unexecuted python code until it is asked to do it. And to
be able to assign it a name, so it would have an object class and
type. But be defined by like a tuple. No addition syntax to make
things confusing.

The (* and *) could be something more appropriate. As long as it's
easy to identify and can't be confused with anything else.


There would be an order of precedence to it also so you could do:

It would execute from the inside (*_*) outward and use the local name
space it's executed in, so no passing arguments or return values.

Nesting and order of precedence has worked for a long time. to
evaluate it you would need a keyword...


or this could be valid:
or left to right order of execution:
If argument passing is really needed, I suppose there could be an
export/inport method attached to it.


A differnt name would be nice... code, docode, dothis, process... ?

or if you require the in_out method to start it, you don't need the
keyword.



Yes, there are probably loads of stuff wrong with this. ;-)

Ron Adam

(Looks like another Ron joined the group.)
 
A

Antoon Pardon

Op 2005-03-22 said:
Not exactly in fact - unless I messed something. There are 2 problems
here: a more flexible tuple unpacking, *and* a lambda in disguise.
Actually, I'd go + 1 for the first, -1 for the second

The proposed syntax from Kay is lambda in disguise. To make it work like
George want it is modifying the unpacking behaviour. Actually while Kay
proposed his syntax as result of the discussion started by George it won't
work for that case. The reason is simply that the lambda form returns a
tuple, but does not make any revelations about the variable names that
tuple shall be unpacked to.

So they are in fact unrelated - at least if introduced as declared. An
augmentation to fulfill George's wishes could look like this:

[a,b,c for a,b,c: (x,y,z=0)-> x,y,z) in values]
Yes, one can live without...
<troll>
...and without list comprehensions, __call__ and other special methods,
descriptors, metaclasses, first class functions, builtin datatypes like
lists and dicts, exceptions, dynamic typing, garbage collection, etc
too. Hurray, let's all happily program in assembly !-)
</troll>

You are right, but for lambda in its current limited form short, named
functions are a good replacement. I don't want to get rid of lambda - but
since listcomps got introduced, 95% of my usages of them disappeared.

I don't understand why people always say short named functions are a
good replacement. IMO list comprehensions and generator expressions
use lambda's in disguise. When we write something like
[x * x for x in some_iterator], nobody seems to have problems that
we just write an expression here and nobody is argueing that we
should define a short function. However when people need the
same kind of semantics in their function, being an expression that
is being reevaluated with different values, for which lambda is the
natural candidate, suddenly we should use short named functions.

Can someone who thinks this way, please explain why this is acceptable

[ x * x for x in some_iterator ]

But this is not

map(lambda x: x * x, some_iteraror)

and should be replaced with

def sqr(x): return x * x
map(sqr , some_iterator)
 
B

bruno modulix

Ron said:
ok... thought it out better. :)

Getting a default into a function isn't the problem. Returning the
value to a varable that doesn't exist is.

So then the question is ... is there a way for a function to create a
varable in it's parents namespace that persists after the function is
done?

yes, that'w called a global, and it's UGLY(tm)
.... global G
.... G = 42
....Traceback (most recent call last):

Anyone doing such a thing in my team would be shoot down at once !-)
 
B

bruno modulix

George said:
Yeap.. a simple one-liner can do the trick:

def makeVars(**nameVals):
sys._getframe(1).f_locals.update(nameVals)

try: b
except NameError: print "Before makeVars: NameError"
else: print "Before makeVars: Not NameError"
makeVars(b=2)
try: b
except NameError: print "After makeVars: NameError"
else: print "After makeVars: Not NameError"

Interesting. I'll keep a copy of this one in my cookbook for further
exploration. But I think I would use such a thing in production code.
88
 
B

bruno modulix

Ron said:
I tried it.. Wrote a html reformatter in it a long time ago. Wasn't
tempted to do anything else with it. It was good for that, but I went
a month later and had trouble figuring out how it worked. :)

This was kind of rethorical question !-)
Yes, two different problems. I don't think anything needs to be done
to tuples myself. I tend to use lists more anyway.

They are two different beasts. Note that you don't have anything like
list unpacking, now tuple unpacking is pretty common in Python (swap,
multiple return values, formatted strings and outputs, ...).
As far as anonymous functions go...
(snip prospective code)

Yes, there are probably loads of stuff wrong with this. ;-)

Err... Isn't it a bit more complicated than our actual lambdas ?-)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,277
Latest member
VytoKetoReview

Latest Threads

Top