As-do statements/anonymous blocks in python

I'm open to any changes or criticism. ``` import atexit as atexit.register: # ...do various cleanup tasks... print('Goodbye') # is approximately equivalent to => import atexit def _(): # ...do various cleanup tasks... print('Goodbye') atexit.register(_) # flask example @app.route("/") def hello(): return "Hello World!" # is approximately equivalent to => as app.route('/'): return "Hello World!" @app.route('/user/<username>') def show_user_profile(username): # show the user profile for that user return 'User %s' % username as app.route('/user/<username>') do username: return "Hello World!" def print_sorted(iterable, block): sorted(iterable, ) l = [1, 2, 3, 4, 'spam'] as l.sort(key=%) do obj: return str(obj) # multiple arguments as spam do a, b: ... ``` ## `%` function call syntax Calling a function with a single percent in place of an argument creates a new function. ``` lumberjack(15, %) # is equivalent to the expression lambda x: lumberjack(15, %) ``` Using `*` instead of `%` could also be possible. ``` import threading, time def interval(seconds, block): def target(): while True: time.sleep(seconds) if block(): # stop looping if block returns True break threading.Thread(target=target).start() as interval(5, %): print("chirp") # => chirp every 5 seconds on a seperate thread as threading.Timer(5, %): print("hi") # => say "hi" in 5 seconds ``` ## `^` currying function definition syntax? I'm not sure this is necessary or a good idea. ``` def interval(seconds, ^block): def target(): while True: time.sleep(seconds) if block(): # stop looping if block returns True break threading.Thread(target=target).start() # is aprroximately equivalent to def interval(seconds, block=None): def inner(block): def target(): while True: time.sleep(seconds) if block(): break threading.Thread(target=target).start() if block == None: def outer(block): return inner(block) else: return inner(block) as interval(5): print('chirp') # equivalent to interval(5)(lambda: print('chirp')) ``` ### Lazy evaluation of chained `%` calls? This would allow things like: ``` start_on_new_thread = threading.Thread(target=%).start() def bong(): while True: time.sleep(6*60) print('BONG') start_on_new_thread(bong) # alternatively as start_on_new_thread: while True: time.sleep(6*60) print('BONG') ``` ## As-do statements in classes ``` class M(): def __init__(self): self.time = 5 as interval(self.time, %): print('chirp') ``` I'm not sure if this should be valid, and I'd like the community's input on when as-do statements should be bound when as-do. ## Proposed Type Hinting Syntax ``` as app.route('/user/<username>') do (username: str): return "Hello World!" ``` Alternatives: ``` as app.route('/user/<username>') do username: str% return "Hello World!" # like objective-c as app.route('/user/<username>') do username: str^ return "Hello World!" # like coffeescript as app.route('/user/<username>') do username: str -> return "Hello World!" ``` I’m not totally sure of practical uses, but I’m imagining it would make passing a function to another function much more convenient. In React, you pass an argument called `render` to a `FlatList`, and `render` renders an item of the list. `FlatList` is a scrollable list that handles unloading off-screen items and loading items that will appear in the scroll box soon.

I like the concept, and I several times wished I could have had a reference to the block of code in a `with` clause. However, it is unlikely to happen: 1 - Guido restricted lambda to one expression, and this would just be a way around that 2 - This will be tempting to use for callbacks and chaining things, leading to the nesting hell we tried very carefully to avoid fom other languages. The example for sorted is also kinda twisted. 3 - Most of the example (and you show it yourself with flask) are already possible with a more verbose syntaxe based on decorators. Example: @atexit.register def _(): print('Goodbye') 4 - introducing a new keyword is the hardest thing you can ever ask on this list. Le 25/07/2018 à 19:07, James Lu a écrit :

You mean lambda x: lumberjack(15, x) ? So you'd want a better syntax for functools.partial, here your example is partial(lumberjack, 15). However this syntax you allow to write lumberjack(%, 15) which is only possible with partial using keyword arguments, like lumberjack (y=15) (given that the second argument is called "y") and in that case I know at least one library on pip doing the job with Ellipsis : from funcoperators import elipartial elipartial(lumberjack, ..., 15) # gives lambda x: lumberjack (x, 15) elipartial (lumberjack, ..., 15, ..., 12, ...) # gives lambda x, y, z: lumberjack(x, 15, y, 12, z) And the lib even provide a decorator to have that kind of syntax using "[" : partially(lumberjack)[15] would be the same as partial(lumberjack, 15) So, that functionality does really need new syntax. Le jeu. 26 juil. 2018 à 14:07, Michel Desmoulin <desmoulinmichel@gmail.com> a écrit :

I *think* you are trying to find a syntax for "code blocks" like Ruby has, but I'm not sure. Your examples are a little confusing to me (possibly because you have at least three separate suggestions here, "as" blocks, a mysterious "do" keyword I don't understand, and partial application using % as argument placeholder). Many people have tried to find a syntax for code block expressions, none have succeeded. Please note that being an *expression* is critical. We already have syntax for code block statements, it is the "def" keyword. You probably ought to spend a few days searching the mailing list archives for previous discussions before you get your hopes up. Before I spend any more time on this proposal, I'll skip right to the end of your post: On Wed, Jul 25, 2018 at 01:07:50PM -0400, James Lu wrote:
I’m not totally sure of practical uses,
If you don't have practical uses, this proposal has ZERO chance of being accepted. Sometimes we can't get proposals accepted even with practical uses.
but I’m imagining it would make passing a function to another function much more convenient.
I don't see how it can be more convenient than: function(another_function) -- Steve

I like the concept, and I several times wished I could have had a reference to the block of code in a `with` clause. However, it is unlikely to happen: 1 - Guido restricted lambda to one expression, and this would just be a way around that 2 - This will be tempting to use for callbacks and chaining things, leading to the nesting hell we tried very carefully to avoid fom other languages. The example for sorted is also kinda twisted. 3 - Most of the example (and you show it yourself with flask) are already possible with a more verbose syntaxe based on decorators. Example: @atexit.register def _(): print('Goodbye') 4 - introducing a new keyword is the hardest thing you can ever ask on this list. Le 25/07/2018 à 19:07, James Lu a écrit :

You mean lambda x: lumberjack(15, x) ? So you'd want a better syntax for functools.partial, here your example is partial(lumberjack, 15). However this syntax you allow to write lumberjack(%, 15) which is only possible with partial using keyword arguments, like lumberjack (y=15) (given that the second argument is called "y") and in that case I know at least one library on pip doing the job with Ellipsis : from funcoperators import elipartial elipartial(lumberjack, ..., 15) # gives lambda x: lumberjack (x, 15) elipartial (lumberjack, ..., 15, ..., 12, ...) # gives lambda x, y, z: lumberjack(x, 15, y, 12, z) And the lib even provide a decorator to have that kind of syntax using "[" : partially(lumberjack)[15] would be the same as partial(lumberjack, 15) So, that functionality does really need new syntax. Le jeu. 26 juil. 2018 à 14:07, Michel Desmoulin <desmoulinmichel@gmail.com> a écrit :

I *think* you are trying to find a syntax for "code blocks" like Ruby has, but I'm not sure. Your examples are a little confusing to me (possibly because you have at least three separate suggestions here, "as" blocks, a mysterious "do" keyword I don't understand, and partial application using % as argument placeholder). Many people have tried to find a syntax for code block expressions, none have succeeded. Please note that being an *expression* is critical. We already have syntax for code block statements, it is the "def" keyword. You probably ought to spend a few days searching the mailing list archives for previous discussions before you get your hopes up. Before I spend any more time on this proposal, I'll skip right to the end of your post: On Wed, Jul 25, 2018 at 01:07:50PM -0400, James Lu wrote:
I’m not totally sure of practical uses,
If you don't have practical uses, this proposal has ZERO chance of being accepted. Sometimes we can't get proposals accepted even with practical uses.
but I’m imagining it would make passing a function to another function much more convenient.
I don't see how it can be more convenient than: function(another_function) -- Steve
participants (5)
-
James Lu
-
Michel Desmoulin
-
Rhodri James
-
Robert Vanden Eynde
-
Steven D'Aprano