Re: Syntax Suggestion: Pass Function Definition as Argument

2019-11-11 Thread Rhodri James

On 07/11/2019 13:36, Stephen Waldron wrote:

This is how it is at the moment, however it may be more agreeable, especially 
if that is the only purpose of the function, for python users to be able to 
define new functions inside of function calls.


No, not seeing it.  Sorry, I don't think "I don't want to use up a 
precious, precious name in this namespace" is a good enough reason to do 
anything, never mind something with a lot of implicit naming going on. 
Suppose you had been good and made a module of your Book example.  What 
is someone reading your code supposed to make of this?


import books

my_books = [
books.Book("Triplanetary", 'E.E. "Doc" Smith'),
books.Book("Foundation", "Isaac Asimov")
]

books.doToBooks(my_books):
print(book.name, ":", book.author)
then:
if book.name == "Foundation":
print("READ THIS FIRST!")

The name "book" has just appeared out of thin air, and without stopping 
and reading the code of your module they will have to guess at what it 
is.  Now in this case their first guess is probably right, but this is a 
toy example and just as easily written with lambdas if you're that 
worried about using up names.


-10 from me.

--
Rhodri James *-* Kynesim Ltd
--
https://mail.python.org/mailman/listinfo/python-list


Re: Syntax Suggestion: Pass Function Definition as Argument

2019-11-08 Thread Stephen Waldron
Ok firstly, this idea was inspired specifically by a project I'm working on for 
school concerning linked lists, in which I was trying to create a method that 
performed a function on elements iteratively without having to navigate the 
list from the head each time (of course taking the function as a parameter). 
This project is intended to be a personal module for future use. 

In the process of this discourse here, however, I think I've found an 
alternative for this specific issue, (so thanks guys) but generally speaking, 
there were other times I've wanted to use functions as parameters, typically 
while making personal modules, like a purely Js button module I had made a few 
years back, and it was apparent that the only way to do so in Python was to 
define first, then pass, which I simply didn't like the idea of in the context 
of a module, short of defining each function before the module instances with 
`def temp(*args):` or some other generic name I won't use past the module 
function instance.

Now yes, as many of you have pointed out, there may exist other workarounds for 
various instances in which one may think to use a function as an argument. 
Multi-line lambdas are a very intriguing method for the broad topic, (thanks, 
they will be useful in the future ^ ^b ++), but as @Chris Angelico mentioned, 
they can't really be used as replacements for def, and from what I've 
experienced trying them out, it wasn't always clear what could be done for some 
of the lines one would want to write.

Finally, some clarification for @David Raymond
> Isn't this basically just defining a function... but without an argument 
> list? How would that know what "str" is?

In my original post, I said:
> If they are not, they won't be assigned to, which would cause an error unless 
> a default value is given. These parameters could be available for passing in 
> the annexed function if mentioned when the parameter is called.

Nyeh, it's written poorly, but I guess I should clarify by saying that, per the 
proposal, arguments are inherent from the parent function to the annexed 
function if and only if that argument is assigned to when the annexed function 
is called as the parameter it fills in the parent function's definition. Of 
course it can also use all other variables within it's scope.

In the example you're referring to, this is done on line 3:
foo (str = str1)
making foo inherit "str" from myFoo, which was given the default value " ".

(I would suppose another viable alternative would be using nonlocal as I'll 
example below)

Also you ask if it's just defining a function. In all of my examples, I use 
only one instance of the parent function (which is actually pretty useless), 
but the power in doing this actually lies in calling it in various locations 
and passing different arguments and annexing different functions (kinda what 
functions are for, haha). I might be hard-pressed to think of an example short 
of writing out a more complex program, but here is.. something?.. I guess 
simply assume runOpt(prompt, foo) is a previously defined function, and 
variables used in the annex are within the annexed function's scope, but prompt 
is not inherited:


runOpt ("Play Game"):
getUserData()
chr[0].id = 0
time = 0
score = 0

scene = 1


runOpt ("How To Play"):
nonlocal prompt

loadBg()
display(prompt)

scene = 2


runOpt ("Settings"):
checkDefaults()
chr[0].id = 5

scene = 3





N.B. on everything (also some TLs you could skip): 
This is just a suggestion, I think it would be nice for previously stated 
reasons (ease, aesthetics, function, yadda-yadda). I would still love to hear 
ways I could currently achieve things similar, as that is one of the things I 
look for from suggestions since "I don't know how to do x right now and have 
not previously found a solution" is implied, but one trigger I do have is a 
reply of "that is not the way it is" to a "this is how I think it should be" 
statement; doesn't give me any hint as to the merits or demerits of my thought, 
as flawed as it may indeed be, in logistics, implementation, practice etc. 
Can't really say anyone has done that quite yet, but just making it known, so 
"What you can try" and "The suggestion is impractical because..." responses are 
welcome. 

Also, one of the reasons for my suggestions is ease. The structure used is 
fairly common in Python, and thus fairly intuitive (I hypothesize at least). I 
know from experience that once you learn something, it becomes fairly easy and 
intuitive for you, but not necessarily for others and you sometimes forget the 
struggle you endured to get there. Of course I'm not saying others shouldn't 
have to learn to, but if there's a way to make it easier for others, I'd push 
it. Now I am still going to learn all about async, await, yield (which I think 
deserves more cred from what I can see so far), and lambda (cuz I wanna) but if 
I think learning and 

Re: Syntax Suggestion: Pass Function Definition as Argument

2019-11-08 Thread Chris Angelico
On Fri, Nov 8, 2019 at 11:22 PM Antoon Pardon  wrote:
>
> On 8/11/19 13:00, Chris Angelico wrote:
> > On Fri, Nov 8, 2019 at 10:57 PM Antoon Pardon  wrote:
> >> On 7/11/19 18:10, Stephen Waldron wrote:
> >>> What I'm aiming for is the ability to, within a function call, pass a 
> >>> suite that would be there automatically defined by the 
> >>> compiler/interpreter. Another comment did mention lambda functions, which 
> >>> does to some degree provide that capability, but is restricted to well, 
> >>> lambda functions (only expressions, not statements).
> >> I don't think those restrictions are that limiting. Certainly not since
> >> python3.8 and python acquired an assigment operator. And you should also
> >> note that a list is an expression. So we could do something like the
> >> following.
> >>
> > If you're implying that you can rewrite any function using lambda and
> > a list of expressions, then no, the ":=" operator won't help you:
> >
>  (lambda: x := 1)
> >   File "", line 1
> > SyntaxError: cannot use named assignment with lambda
>
> Well I haven't had the time to install python3.8 myself but this is what
> I read in the PEP
>
> * Unparenthesized assignment expressions are prohibited in lambda
> functions. Example:
> (lambda: x := 1) # INVALID
> lambda: (x := 1) # Valid, but unlikely to be useful
> (x := lambda: 1) # Valid
> lambda line: (m := re.match(pattern, line)) and m.group(1) # Valid
>
> This allows lambda to always bind less tightly than :=; having a
> name binding at the top level inside a lambda function is unlikely
> to be of value, as there is no way to make use of it. In cases where
> the name will be used more than once, the expression is likely to
> need parenthesizing anyway, so this prohibition will rarely affect code.
>
> So it seems you just forgot to use the parenthesis.
>

True, I could make it syntactically valid with parens. But as the
paragraph shows, it's still not possible to use it outside that lambda
function (there's no way to declare it nonlocal), and you can't assign
to anything other than a simple name (no "x[1] := 1"), so you still
can't use this as a true replacement for 'def' functions. I kinda
shorthanded with the example but it's still a very tight limitation.

Going back to looking at the way JavaScript does things, though: One
of the main places that large functions are commonly used as arguments
is asynchronous code. There are better ways to do that (async/await in
both languages, threads and processes in Python), so that's not
necessary. For event driven code, I would much prefer to use 'def'
functions with decorators, rather than function arguments - compare a
bit of Python/Flask code with a similar bit of JS/Express:

@app.route("/foo/")
def foo(id):
return ...

app.get("/foo/:id", (req, res) => {
res.send(...)
});

Pretty similar, but one very important distinction is that the Flask
style extends easily to multi-routing, simply by decorating the
function more than once.

For event-driven code (this is for an HTTP server, and the same
applies to a GUI), this is a way cleaner way to do things. I'd rather
look into ways to make decorators do what you need (even if that
involves an enhancement to decorator syntax) than try to create
multi-line lambdas.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Syntax Suggestion: Pass Function Definition as Argument

2019-11-08 Thread Antoon Pardon
On 8/11/19 13:00, Chris Angelico wrote:
> On Fri, Nov 8, 2019 at 10:57 PM Antoon Pardon  wrote:
>> On 7/11/19 18:10, Stephen Waldron wrote:
>>> What I'm aiming for is the ability to, within a function call, pass a suite 
>>> that would be there automatically defined by the compiler/interpreter. 
>>> Another comment did mention lambda functions, which does to some degree 
>>> provide that capability, but is restricted to well, lambda functions (only 
>>> expressions, not statements).
>> I don't think those restrictions are that limiting. Certainly not since
>> python3.8 and python acquired an assigment operator. And you should also
>> note that a list is an expression. So we could do something like the
>> following.
>>
> If you're implying that you can rewrite any function using lambda and
> a list of expressions, then no, the ":=" operator won't help you:
>
 (lambda: x := 1)
>   File "", line 1
> SyntaxError: cannot use named assignment with lambda

Well I haven't had the time to install python3.8 myself but this is what
I read in the PEP

    * Unparenthesized assignment expressions are prohibited in lambda
functions. Example:
    (lambda: x := 1) # INVALID
    lambda: (x := 1) # Valid, but unlikely to be useful
    (x := lambda: 1) # Valid
    lambda line: (m := re.match(pattern, line)) and m.group(1) # Valid

This allows lambda to always bind less tightly than :=; having a
name binding at the top level inside a lambda function is unlikely
to be of value, as there is no way to make use of it. In cases where
the name will be used more than once, the expression is likely to
need parenthesizing anyway, so this prohibition will rarely affect code.

So it seems you just forgot to use the parenthesis.

-- 
Antoon Pardon

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Syntax Suggestion: Pass Function Definition as Argument

2019-11-08 Thread Chris Angelico
On Fri, Nov 8, 2019 at 10:57 PM Antoon Pardon  wrote:
>
> On 7/11/19 18:10, Stephen Waldron wrote:
> > What I'm aiming for is the ability to, within a function call, pass a suite 
> > that would be there automatically defined by the compiler/interpreter. 
> > Another comment did mention lambda functions, which does to some degree 
> > provide that capability, but is restricted to well, lambda functions (only 
> > expressions, not statements).
> I don't think those restrictions are that limiting. Certainly not since
> python3.8 and python acquired an assigment operator. And you should also
> note that a list is an expression. So we could do something like the
> following.
>

If you're implying that you can rewrite any function using lambda and
a list of expressions, then no, the ":=" operator won't help you:

>>> (lambda: x := 1)
  File "", line 1
SyntaxError: cannot use named assignment with lambda

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Syntax Suggestion: Pass Function Definition as Argument

2019-11-08 Thread Antoon Pardon
On 7/11/19 18:10, Stephen Waldron wrote:
> What I'm aiming for is the ability to, within a function call, pass a suite 
> that would be there automatically defined by the compiler/interpreter. 
> Another comment did mention lambda functions, which does to some degree 
> provide that capability, but is restricted to well, lambda functions (only 
> expressions, not statements).
I don't think those restrictions are that limiting. Certainly not since
python3.8 and python acquired an assigment operator. And you should also
note that a list is an expression. So we could do something like the
following.

class Book:
    def __init__(self, name, author):
self.name = name
self.author = author


def doToBooks (bookList, first, then, book = None):

for book in bookList:
first(book = book)
then(book = book)

myBooks = [
Book("The Way of the World", "Lucy Cole"),
Book("To Live or To Love", "Georgio Dunham"),
Book("Twelve Days of Success", "Anita Duvette")
]
import sys
write = sys.stdout.write

doToBooks (myBooks,
   first = lambda book: [write(book.name), write("\n")],
   then = lambda book: [write(" - "), write(book.author), write("\n")]
  )

The above code will print the following:

The Way of the World
 - Lucy Cole
To Live or To Love
 - Georgio Dunham
Twelve Days of Success
 - Anita Duvette

-- 
Antoon.

-- 
https://mail.python.org/mailman/listinfo/python-list


RE: Syntax Suggestion: Pass Function Definition as Argument

2019-11-07 Thread David Raymond
Here is it rewritten using the proposal:
```
#Definition
def myFoo (str1, str2, foo, str = " "):
print( foo(str = str1), foo(str = str2) )


#Call
myFoo ("hello", "world!"):
str = list(str)[0].upper() + str[1:]
return str
```

Are you looking for multi-line lambdas?
Isn't this basically just defining a function... but without an argument list? 
How would that know what "str" is?

Since you can already define functions inside of functions, what functionality 
does this give you that you can't already do with something like this:

def myFoo(str1, str2, foo):
print(foo(str1), foo(str2))

def main():
print("Stuff here")

def f1(str):
str = list(str)[0].upper() + str[1:]
return str
myFoo("hello", "world", f1)

def f1(str): #yup, same name
str = str[:-1] + list(str)[-1].upper()
return str
myFoo("hello", "world", f1)

del f1

print("More stuff")

main()


Which results in:
Stuff here
Hello World
hellO worlD
More stuff

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Syntax Suggestion: Pass Function Definition as Argument

2019-11-07 Thread Stephen Waldron
Thanks Antoon. I do suppose that it is kind of wrong to say the only way is to 
"reference its [the function's] name" as an argument, however the point I was 
trying to make was that it isn't possible to pass a function that is either not 
in some way previously defined or a reference to something previously defined.

In your example, you still make reference to the existing function `truediv` 
from the `operator` library, even though the `partial` function does create a 
new function.

What I'm aiming for is the ability to, within a function call, pass a suite 
that would be there automatically defined by the compiler/interpreter. Another 
comment did mention lambda functions, which does to some degree provide that 
capability, but is restricted to well, lambda functions (only expressions, not 
statements).

Your example does however suggest the possibilities of a function or expression 
that creates functions. For example, the `function` expression in JavaScript.

```
//Definition
function myFoo (str1, str2, foo){
console.log( foo(str1), foo(str2) );
}


//Call
myFoo ("hello", "world!", function(str){

str[0] = str[0].toUpper();
return str;

});


Output:
Hello World!
```

However it does not seem that there would be any such expression in Python as 
is. In python, this code would be written:


```
#Definition
def myFoo (str1, str2, foo):
print( foo(str1), foo(str2) )


#Call
def other_foo(str):
str = list(str)[0].upper() + str[1:]
return str

myFoo ("hello", "world!", other_foo)

```


Here is it rewritten using the proposal:
```
#Definition
def myFoo (str1, str2, foo, str = " "):
print( foo(str = str1), foo(str = str2) )


#Call
myFoo ("hello", "world!"):
str = list(str)[0].upper() + str[1:]
return str

```

Of course this example presents only a minor, though you can see the difference 
in the call, in which no new function needs be referenced.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Syntax Suggestion: Pass Function Definition as Argument

2019-11-07 Thread Stephen Waldron
Thanks Antoon. I do suppose that it is kind of wrong to say the only way is to 
"reference its [the function's] name" as an argument, however the point I was 
trying to make was that you cannot pass a function that is either not in some 
way previously defined or a reference to something previously defined.

In your example, you still make reference to the existing function `truediv` 
from the `operator` library, even though the `partial` function does create a 
new function.

What I'm aiming for is the ability to, within a function call, pass a suite 
that would be there automatically defined by the compiler/interpreter. Another 
comment did mention lambda functions, which does to some degree provide that 
capability, but is restricted to well, lambda functions (only expressions, not 
statements).

Your example does however suggest the possibilities of a function or expression 
that creates functions. For example, the `function` expression in JavaScript.

```
//Definition
function myFoo (str1, str2, foo){
console.log( foo(str1), foo(str2) );
}


//Call
myFoo ("hello", "world!", function(str){

str[0] = str[0].toUpper();
return str;

});


Output:
Hello World!
```

However it does not seem that there would be any such expression in Python as 
is. In python, this code would be written:


```
#Definition
def myFoo (str1, str2, foo):
print( foo(str1), foo(str2) )


#Call
def other_foo(str):
str = list(str)[0].upper() + str[1:]
return str

myFoo ("hello", "world!", other_foo)

```


Here is it rewritten using the proposal:
```
#Definition
def myFoo (str1, str2, foo, str = " "):
print( foo(str = str1), foo(str = str2) )


#Call
myFoo ("hello", "world!"):
str = list(str)[0].upper() + str[1:]
return str

```

Of course this example presents only a minor, though you can see the difference 
in the call, in which no new function needs be referenced.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Syntax Suggestion: Pass Function Definition as Argument

2019-11-07 Thread Antoon Pardon
On 7/11/19 14:36, Stephen Waldron wrote:
> Hi, I'm new to the group and to Python, so forgive me if I make any faux-pas 
> here. As I can tell, the only way to pass a function as an argument is to 
> reference its name as follows:
>
> def foo1(message):
> print(message)
>
> def foo2(foo, message):
> print("Your function says:")
> foo(message)

No that is not true. "map" is a function that takes a function as its
first argument. But I can do the following if I want to produce the
inverses of a list of numbers.

from operator import truediv
from functools import partial

ls = range(1, 11)

for x in map(partial(truediv, 1), ls):
print(x)

In the code above "partial(truediv, 1)" will produce a function that
will inverse its argument and I don't need to give this function a name
to pass it as an argument in an other function.

-- 
Antoon Pardon.
-- 
https://mail.python.org/mailman/listinfo/python-list


Syntax Suggestion: Pass Function Definition as Argument

2019-11-07 Thread Stephen Waldron
Hi, I'm new to the group and to Python, so forgive me if I make any faux-pas 
here. As I can tell, the only way to pass a function as an argument is to 
reference its name as follows:

def foo1(message):
print(message)

def foo2(foo, message):
print("Your function says:")
foo(message)


>>foo2(foo1, "Hello World!")
Your function says:
Hello World!


This is how it is at the moment, however it may be more agreeable, especially 
if that is the only purpose of the function, for python users to be able to 
define new functions inside of function calls. The way I propose this may occur 
is using similar syntax as control structures, as exampled below:

def foo2(foo):
print("Message to print:", end = " ")
foo()


>>foo2():
print("Hello World!")

Message to print: Hello World!


In this proposal, it should be noted, that unlike control structures, the 
brackets are required for the function call. The "suite" or "annex" is defined 
as a function object by the compiler and passed inside the call. Here are some 
other examples of the proposal.



*Non-Function Arguments with Annexed Functions*
Non-Function Arguments should be placed in the brackets before annexed 
functions, and this should be reflected in the parameter order. If they are 
not, they won't be assigned to, which would cause an error unless a default 
value is given. These parameters could be available for passing in the annexed 
function if mentioned when the paramaeter is called.

def myFoo (num1, num2, foo):
return foo (num1, num2)


>>myFoo(20, 30):
return num1 + num2

50


*Annexing Multiple Functions or Out of Order Annex*
To specify the order in which functions are annexed, or annex multiple 
functions, one could use the parameter name before the specific suite.

class Book:
def __init__(self, name, author):
self.name = name
self.author = author


def doToBooks (bookList, first, then, book = None):

for book in bookList
first(book = book)
then(book = book)

myBooks = [
Book("The Way of the World", "Lucy Cole"),
Book("To Live or To Love", "Georgio Dunham"),
Book("Twelve Days of Success", "Anita Duvette")
]

doToBooks (myBooks):
print(book.name)
then:
print(" - " + book.author + "\n")



>
The Way of The World
 - Lucy Cole

To Live or To Die
 - Georgio Dunham

Twelve Days of Success
 - Anita Duvette



This proposal does not detract from the core appearance and appeal of Python 
while creating an option for users and module makers who want themselves or the 
users of their modules not to have to previously define functions in order to 
use the code. This would make such code more aesthetic and compact, and take 
away the need for defining a new function, name and all, specifically for such 
which ultimately would be used only once as an argument. 
   
-- 
https://mail.python.org/mailman/listinfo/python-list