Code blocks and a possible syntax

Miscellaneous idea I had. Code blocks! A way to:
A create a new scope
B modify python code without needing to wrap it in a function first
C store code in a pythonic way

The simplest example of the concept is :

code_bock : 

    #statments go here
    do_important_thing() 
    foo="bar"
    print("foo is", foo)  #prints "foo is bar" 

print("foo is", foo)  #fails because foo is not defined in this scope

The main other uses are modifying the code mid-execution

class my_transtormer(ast.NodeTransformer):
    def vist(self, node) :
        return node

@my_transformer().vist
code_block :
    print("hello world!") 

With this usage the code in the code block is converted to an ast node before being passed to the decorator. The code is then executed.

The last use is to create a piece code to store for later use.

code_block as my_code:
    print (" hello world")

#nothing is printed immediately

exec (my_code) # results in "hellow world" being printed

This allows code to be created and stored without needing to store it as a string well as allowing the user of decorators.

What’s the disadvantage of using a function? To a regular user, this will look like just a function without the def. You can always modify the behaviour of a function by writing if-statements in the function (granted, you can’t do this after the fact, but I would say that’s a benefit for code readability)


I’m also going to preempt the discussion of inserting code directly into the AST by readying the inline-function discussions: Inline Python functions and methods - Ideas - Discussions on Python.org and Adding inline in Python - Ideas - Discussions on Python.org

3 Likes

I meant the decorator syntax as a way to modify the ast of code then run it immediately. Not as an alternative to def. Currently if you want to modify the ast of some code the only way is:

def temp_func() :
    print("very important code") 

tree=ast.parse(inspect. getsource(temp_func),__name__) 
my_transtormer().visit(tree)
tree[1].name="_"
code=compile(ast.Module([tree[1],
           ast.Return(ast.name("_",ast.Load()) )])
eval(code)() 

As opposed to my proposed syntax:

@my_transtormer().visit
code_block:
    print("very important code ") 

Does this correspond to Labels and goto in C?

No. It is a way to make using an ast modifier easier.

Is there a good reason to have an AST[1] modifier? I can tell you from experience that having complex function decorators drastically increases the cognitive burden on future readers of the code. What’s an example where you would want to modify the AST and it wouldn’t make sense to achieve the same outcome more explicitly?


  1. AST: abstract syntax tree, for those who don’t know ↩︎