On Fri, Oct 01, 2021 at 03:35:26PM -0400, Jonathan Crall wrote:

> My motivation for writing this suggestion is in an attempt to stop a common
> anti-pattern, where instead of defining a `main` function (or a function by
> any other name) an simply calling that by adding the above two lines, a lot
> of Python users I work with will just start dumping their logic into the
> global scope of the module.
> 
> Needless to say, this can have consequences.

What sort of consequences are you thinking of, under what circumstances?

Remember, Python is first and foremost a scripting language. There's 
nothing wrong with writing scripts that run in the global scope.


> If there was some default
> builtin, let's call it `__main__` for now (open to suggestions), that took
> a function as an argument and conditionally executed it if `__name__ ==
> "__main__"` in the caller's scope, that would allow us to simplify the
> above boilerplate to a single line with no extra indentation:
> 
> ```
> def main():
>     ...
> 
> __main__(main)
> ```

You don't need `__main__` to be built into the interpreter. It's a 
two-line pattern: not every two line function needs to be a builtin.


```
def __main__(func):
    if __name__ == '__main__': func()
```


Put that in a module, then:

```
from module import __main__
```

in all your scripts.

If you're worried about keystrokes, and your editor doesn't have a 
"snippets" functionality, you can put your `__main__` in your 
PYTHONSTARTUP file or sitecustomize.py and have it loaded automatically 
into builtins.

https://pymotw.com/3/site/

```
import builtins
builtins.__main__ = __main__
```


> In addition to being simpler, it would allow users to avoid the trap of
> adding logic that impacts the global scope.

There is nothing necessarily wrong with logic that impacts the global 
scope in a script. It can be the easiest thing that works. The more 
complex your system, the more there is to go wrong.

Is your definition of simpler based on counting keystrokes? The 
underlying complexity is the same. Your builtin `__main__` performs 
exactly the same conditional test, it's just buried behind a function 
call.


> Furthermore, it could be used as a decorator (and the use-case wouldn't be
> unreasonable!), and we all know how much new Python users love decorators
> when they find out about them.

Are you being sarcastic? The idiom "We all know how much X love Y" is 
typically (but not always) used sarcastically.

Decorator syntax has been a great success for Python, but even to this 
day newbies often struggle to understand them and even some experienced 
users avoid them.

My completely unscientific, pluck-a-figure-out-of-the-air guestimate is 
that about 10% of Python users treat decorators as a hammer and every 
problem they see as a nail, another 10% find them to be utterly 
perplexing and a source of dread, 20% know how to cut-and-paste a recipe 
involving decorators when needed, but don't know how they work (and have 
no interest in learning), and the rest have some reasonable level of 
understanding of how to use decorators and write their own.

In this particular case, using decorator syntax:

    @__main__
    def main(): ...

to call the function immediately, rather than the more straightforward

    __main__(main)

seems to me to fall squarely in the "hammer + nail" category. I can't 
tell whether this is a serious proposal on your part or not.


> Maybe having such a builtin would discourage globals and help new users get
> the use-decorators-everywhere bug out of their system.

There is no need to discourage globals for script writing. And I'm not 
entirely sure how it follows that encouraging people to use a decorator 
to run their script main function will discourage them from using 
decorators everywhere. What have I misunderstood?


-- 
Steve
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/YSCULW6535SKXEGCYM7AQDOHINSUWRA3/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to