Re: Syntax Suggestion: Pass Function Definition as Argument
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
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 utili
Re: Syntax Suggestion: Pass Function Definition as Argument
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
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
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
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
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
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
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
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