
An exploration of why Python doesn't require a 'main' function - zdw
https://utcc.utoronto.ca/~cks/space/blog/python/WhyNoMainFunction
======
pansa2
One benefit of using a main function in Python is performance. If you’re doing
significant computation at the top-level, it’ll probably run faster if moved
into a function.

I believe this comes from the fact that local-variable lookup is faster than
global-variable lookup - because the former is lookup-by-index and the latter
is lookup-by-name.

The same is true in Julia: “Any code that is performance critical or being
benchmarked should be inside a function.” [0]

[0] [https://docs.julialang.org/en/v1/manual/performance-
tips/ind...](https://docs.julialang.org/en/v1/manual/performance-
tips/index.html)

~~~
el_programmador
Another benefit is re-usability. If you want your program to be callable as
module or script from elsewhere without going through the tedious shell
functions, "def main()" is the only way to go.

~~~
qw
Would that be different than checking the __name__?

    
    
      if __name__ = "__main__":
          mainMethod()

~~~
el_programmador
The difference is that you've encapsulated your coding logic in mainMethod()
instead of writing under that if condition itself. If latter was the case, you
can't call that code from another module without resorting to os shell level
features.

~~~
Nginx487
The code encapsulated into "__main__" assumed to be module-specific, this is
the purpose of that pattern. If you want to make some code available for
another module, you just refactor it into separate function.

------
jeffreyrogers
I always saw Python and similar languages (Perl, Ruby, PHP maybe) as attempts
at replacements for complicated shell scripts, so it never seemed odd to me
that there was no main function, since a shell script has no main either. It
just starts executing at the top.

Edit: Just saw that ktpsns and I made pretty much the same comment. I'll add
that when I learned C I found the idea of a main function so confusing at
first. I wanted to know why it had to be called main and not whatever else I
wanted it to be. On the plus side, it led to me exploring how compilers and
linkers work, which made me understand hardware a lot better.

~~~
benbristow
Interestingly C# is introducing top-level programs now.

[https://devblogs.microsoft.com/dotnet/welcome-
to-c-9-0/#top-...](https://devblogs.microsoft.com/dotnet/welcome-
to-c-9-0/#top-level-programs)

~~~
CodesInChaos
Looks pretty similar to csx scripts

------
klyrs
There's a big benefit to Python's convention

    
    
      if __name__ == "__main__":
          ...
    

especially in contrast with c and other languages that shoehorn you into
defining a main function. Namely, you can put a "main" into a module, and
import that into another module without causing trouble.

I use this a lot during a development cycle (not so much in prod). Say I'm
trying to replace a function foo with a new implementation foo_new in a large
package. I write some rudimentary tests and benchmarks in "main" which compare
the two methods (including a late-import of the top-level package), and
directly execute that file until I'm satisfied. At that point, I'll switch
(foo, foo_new) -> (foo_old, foo) and start running unit tests. Once those unit
tests pass, I remove "main" (usually, promoting some fragments of it to new
unit tests) and foo_old.

~~~
uryga
> especially in contrast with c and other languages that shoehorn you into
> defining a main function

i don't think that's a problem in languages with namespaces/modules -- a
module might define a main(), it just wouldn't be used when it's imported.
(unless you're in C, then you'd get a name clash)

~~~
klyrs
That's a great point... with a small caveat that some people abuse namespaces
badly and clashes may still occur.

------
JKCalhoun
> Many languages start running your program by calling a function of yours
> that must have a specific name. In C (and many C derived languages), this is
> just called main(); ... Python famously doesn't require any such function...

Nor did BASIC.

I think the better question is, why does C (and C derived languages) require a
main function?

~~~
analog31
Maybe it goes back to assembly language. If you look at a block of assembly or
machine language code, it's not immediately obvious where the entry point is.
You could guess that it's at address 0, but I don't think that's the case for
all machines.

I think more important than having a main() function is to clearly delineate
the entry point. And in Python, the entry point is the first line of the
program.

Now I've noticed, at least within the Arduino environment, that it uses
setup() and loop() as entry points, but code is executed before these
functions are called, if for instance a global variable definition invokes a
class constructor. I don't know if that's how "regular" C works, but it
creates ambiguity as to what runs first.

There are other languages where it seems hard to guess where the actual entry
point is located unless you know where to look.

~~~
ritter2a
You don't get quite this level of ambiguity with standard C, since it does not
provide objects (in the object-oriented sense) with constructors, in contrast
to C++ that is used in the Arduino environment (in C++, initialization order
of global objects is indeed unspecified, inviting subtle bugs to occur).

However, many common C compilers provide methods to declare functions to run
at initialization time, e.g. gcc's `constructor` attribute, opening this
rabbit hole also for C programmers.

------
zelphirkalt
And still I do write a main procedure in Python usually, which is called from
that if __name__ == "__main__" thing. It is convenient to leave the top level
asap and begin as quickly as possible to use procedures/function, getting out
of the area, where one can accidentally change global variables, without
noticing (in procedures you would have to write global as a keyword and would
hopefully then notice you are doing something possibly dangerous).

~~~
quietbritishjim
Absolutely. But on the other hand, it's still very useful that Python does
work like this: it's nice to be able to directly do things at the top level
(e.g. setting up "constants" with a little computation, conditionally
importing modules or importing fallbacks, etc.). As the article says, it's
also an extremely clean way of defining what gets run in what order during
startup.

------
ktpsns
Here's a thing: Coming from a world of Perl, PHP, Ruby, Bash, BASIC, batch
etc. scripts, a main function is not neccessary at all. The procedural code
just starts from the first line.

With this in mind, it is weird to even ask for a main function. :-)

~~~
pantaloony
My immediate reaction was “it does—but it’s in the interpreter so of course
you don’t have to write it”.

~~~
marcosdumay
And you can perfectly well compile them and keep that same behavior.

C's entry point is in the runtime too, it's not your main function (but yeah,
the optimizer will probably inline your main). At the end of the day, there's
no real difference between compiled and interpreted languages, all the
difference is on the toolset.

------
kissgyorgy
Once I worked with a library, which when imported, started printing with a
printer to paper. So yes, your Python program absolutely needs a main function
and please no side effects at import time!

~~~
tdeck
I don't see how these two are the same. No side effects at import time? Sure.
But a program isn't meant to be imported, it's meant to be run, so there's no
real expectation that a program should be importable without side effects.

~~~
shoo
they're not the same, but they're both symptoms of the same underlying python
behaviour: when you run a python file or import a python file, the interpreter
immediately starts executing statements from the top of the file down.

------
riazrizvi
The _main_ function, in C/CPP programs, satisfies an operating standard in
Unix and Windows systems for a defined program instruction entry point. With
CPython, _main_ is written into the _python_ executable's source. Python
scripts are not C/CPP-source executables so they don't need a _main_ , they
don't need this constraint, so what sense is there in imposing it?

~~~
im3w1l
No, this isn't so. And besides, the main function isn't even the first thing
in your program to run. The standard library does some setting up first. For
instance populating argc and argv.

You may enjoy reading this:
[http://www.muppetlabs.com/~breadbox/software/tiny/teensy.htm...](http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html)
It explains a lot of how linux loads programs. It's a bit dated though:
everything is 32 bit.

~~~
sszz
There is definitely a main function in the CPython source code.

------
staycoolboy
This article really complicates a simple concept: EVERY program needs a
main(). Period. Whether it is called "main()" or ".ORG", or it is just an
address given to a linker map, or simply a hex address in a BIOS boot
sequence. There is no avoiding it: one instruction must come first.

Python, Perl, Ruby, Bash and every other scripted interpreted language
IMPLICITLY wraps "main" around your program based on the context, otherwise it
wouldn't know where to start.

I find this article obfuscating a simple point.

EDIT: When I say .ORG, I'm referring to the standard assembly language
designation for "execute this instruction first", and not ICANN. ;)

~~~
munk-a
Yup - and even the most obfuscated language's main (PHP) has a single entry
point - that entry point is just in apache[1] which figures out which of your
bazillion PHP files to execute.

This article is bordering on nitpicking.

1\. Or whatever other webserver - and actually you can directly invoke PHP via
CLI, but I'm ignoring those for the most common way people tend to use it.

------
leoh
Bit snarky, but all I got from this post is "because it doesn't." Many
languages don't require a main function. In fact, the earliest languages like
LISP (and even punchcards!) don't require it, let alone many other languages
like BASIC, awk, etc. The presence of a main function in later languages is,
in a way, the outlier.

~~~
tdeck
FORTRAN does not require one either, as you can see in this example:

[http://www.99-bottles-of-beer.net/language-
fortran-77-264.ht...](http://www.99-bottles-of-beer.net/language-
fortran-77-264.html)

------
heavenlyblue
This does seem like one of those deeply bikeshedded philosophical arguments.

~~~
joshlk
Yes the argument is trivial. But it illuminates design choices of each
language which is interesting

------
irrational
Why do some languages require a main function? I started out with JavaScript
decades ago, and of course JS doesn't require a main function. When I started
learning Java I thought the requirement that there must be a main function was
just bizarre. I still feel that way, it just feels wrong.

~~~
wruza
Because languages that compile to a platform binary must obey rules of a
system linker and a corresponding stdlib. Javascript is an active host for an
entire js program, but C compiler is not. C source files turn into object
files (.o/.obj and then .so/.dll for libraries) that have a particular format
and may be linked with object files and libraries from other languages. A
system linker then decides where the entry point is by looking in every object
file for a _start symbol, which is usually implemented by clib, and it
basically does:

    
    
      void _start(void) {
        extern int main(...);
        init_clib();
        exit(main(...));
      }
    

The exact procedure heavily depends on a build target. Also, C compiler cli
tool (e.g. gcc) is usually a frontend for a compiler and a linker, among other
tools, which may add to the confusion.

Object files are collections of symbols, either external, or defined in that
file. Every non-extern symbol is a region (addr, len) with either data or
code. There is no unnamed/main symbols by design. In theory, C could abstract
that and allow code at column zero, but there is no rationale for that.

------
sudomakeup
Well, the python interpreter has a main function.

This whole topic is like comparing apples to oranges. The python
interpreter(which IS compiled and has a main function) defines the rules of
whats required in python. And it can reasonable assume that the entry point is
the beginning of the .py file its running.

------
z3t4
In JavaScript only functions declared with function first will be hoisted, so
I create my own main function and call it at the end of the file.

------
jimbob45
Why not keep “main” as a reserved function word and just append the magic “if
name == “__main__” behind the scenes if that function is seen? For a language
focused on immediate usability, it’s a stupid first hurdle to have to clear to
greet the world.

~~~
gizmo686
1) One of pythons design philosophies is "explicit is better than implicit".

2) This is not a hurdle to hello world.

    
    
        print("Hello World") 
    

is a complete program that does exactly what you want. Needing to wrap it in a
function would be an additional hurdle.

For complex programs; that is a hurdle well worth jumping. But for simple
scripts (python is a scripting language), or teaching purposes, it is not
always needed.

~~~
kzrdude
Ad 1,

the current idiom uses dunder name, which is implicitly defined and looks
special.

Making main special would be about the same level of a solution, yet more
conventional

~~~
toyg
Dunder methods don’t “look” special, they are. Marking them as such has side-
effects, and as soon as you see a dunder, you know you’re going “lower”.

If “main” has to be a special function, it must keep the dunder.

------
nailer
Better yet, why not explore why other languages insist on having a function,
or a class with methods, before being able to print hello world?

C# literally got the ability to System.out.writeLine("hello world") (probably
wrong, I'm not a C# programmer) in 2020.

I suspect the answer is "we care about existing programmers more than people
who are learning to program".

~~~
flohofwoe
What's the point of teachin newcomers something they need to give up later
anyway though? (once their programs get big enough to be split over several
files)

~~~
auxym
Nim compiles to C, can be split into multiple files/modules, and does not
require a "main" function.

