<p>Some languages, such as C++ and Java, have grammar restrictions where code that is not a declaration or import statement cannot be outside of a function. However, variables, functions, and classes can be freely created at the 'top level'. Other statements are allowed inside functions, where the main function effectively acts as the top level.</p>
<p>This is in contrast to a language like Python which freely allows if statements, loops, and all other constructs to be outside of any functions in the <a href="https://docs.python.org/3/library/__main__.html#what-is-the-top-level-code-environment" rel="nofollow noreferrer">top-level code environment</a>.</p>
<p>What are the pros and/or cons of either approach? In which types of languages might it be useful to enforce declaration only top levels and when might it be alright to allow all kinds of statements at the top level?</p>

<declarations><top-level>
What are the advantages and disadvantages of only allowing declarations at the top level?
CC BY-SA 4.0
2023-05-24T12:48:52.500Z
The third alternative is languages like Swift and C#, where you can have top-level code in up to one file, _or_ you can have a main function.
Bbrk24
CC BY-SA 4.0
2023-05-24T14:06:27.017Z
Related question on CS SE: https://cs.stackexchange.com/q/160004/111482
kaya3
CC BY-SA 4.0
2023-05-24T21:26:00.260Z
At a high level: whenever a thing can’t be nested in something else, you may need to “normalise” the program that you’d rather write, and like expanding a Boolean formula to DNF or CNF, this may scale exponentially. To avoid that, programmers tend to add more names and other abstractions. But the root cause is that the thing isn’t first-class. It’s not necessarily a problem—flatter structures are often easier to understand—but it is a tradeoff.
Jon Purdy
<p>TLDR: Such constructs aren't supportable in all execution environments.</p>
<p>Many high-level language compilers don't generate executable programs directly, but instead produce object files which will then be fed to a linker in order to generate an executable.  Some linkers may provide a mechanism by which multiple object files can contain code which should be run at program startup, without any of the object files knowing about each others' initialization code, but not all linkers support such things.  A language which allows source files to include code which isn't in functions, and which should be run at program startup, would either be unusable with linkers that can't support such constructs, or would cause the range of constructs available to programmers to vary depending upon the linker used.  Such compromises may be acceptable for some language designers, but many prefer to limit languages features to those that linkers can universally support.</p>

CC BY-SA 4.0
2023-11-15T23:04:13.323Z
2023-11-20T17:20:36.423Z
2023-11-20T17:20:36.423Z
supercat
<h2>Boilerplate for small projects</h2>
<p>Java has an infamously verbose “hello world” due to the amount of boilerplate required to run anything. Python and JS, on the other hand, both have one-liners.</p>
<h2>Imports with side effects</h2>
<p>When you <code>require</code> a file in JS, all top-level code in that file is run, which can have side effects. Sometimes this is useful (e.g. a master test script can just <code>require</code> each individual test), but usually this is unwanted. Some languages, like Swift and C#, get around this by only allowing one file per project with top-level code.</p>

CC BY-SA 4.0
2023-05-24T12:55:36.953Z
2023-05-24T12:55:36.953Z
Bbrk24
CC BY-SA 4.0
2023-05-24T14:23:13.210Z
Hello, world, is getting shorter in the next version of Java (not very smart, I'd say, if you read the relevant JEP)
Seggan
<p>Whether to allow top-level statements is mostly a matter of technical considerations.</p>
<p>In compiled languages, statically typed languages, it is necessary to create a complete list of top-level functions to be able to properly compile them. For compiled programs these functions may be exposed individually and called by external programs that may link to your bundle. Fundamentally your program will compile into a set of functions with maybe some related data, perhaps with also a entry point which is just another function and can also be called by external libraries.</p>
<p>On the other hand, in more dynamic interpreted languages functions may be created, destroyed, and modified on the fly. A function declaration is just another type of statement, and it won't exist until then. There is no real difference between the inside and outside the function, all code will be run one by one top to bottom. If functions are just expressions it makes sense to allow other expressions too where functions are allowed.</p>
<p>If you fall into neither of these categories, the choice is up to you. Allowing only functions at the top level can make type checking easier, but also adds more boilerplate.</p>

CC BY-SA 4.0
2023-05-24T13:39:16.763Z
2023-05-24T14:00:11.550Z
2023-05-24T14:00:11.550Z
mousetail 'he-him'
# What are the advantages and disadvantages of only allowing declarations at the top level?
Posted by: username_0 on 2023-05-24
Some languages, such as C++ and Java, have grammar restrictions where code that is not a declaration or import statement cannot be outside of a function. However, variables, functions, and classes can be freely created at the 'top level'. Other statements are allowed inside functions, where the main function effectively acts as the top level.

This is in contrast to a language like Python which freely allows if statements, loops, and all other constructs to be outside of any functions in the [top-level code environment](https://docs.python.org/3/library/__main__.html#what-is-the-top-level-code-environment).

What are the pros and/or cons of either approach? In which types of languages might it be useful to enforce declaration only top levels and when might it be alright to allow all kinds of statements at the top level?
**Tags:** declarations top-level
> **Comments:**
> **username_1**: The third alternative is languages like Swift and C#, where you can have top-level code in up to one file, _or_ you can have a main function.  
> **username_2**: Related question on CS SE: https://cs.stackexchange.com/q/160004/111482  
> **username_3**: At a high level: whenever a thing can’t be nested in something else, you may need to “normalise” the program that you’d rather write, and like expanding a Boolean formula to DNF or CNF, this may scale exponentially. To avoid that, programmers tend to add more names and other abstractions. But the root cause is that the thing isn’t first-class. It’s not necessarily a problem—flatter structures are often easier to understand—but it is a tradeoff.  
---
## 3 answers
### Answer by username_6 on 2023-05-24. Score: 6 | Accepted answer
Whether to allow top-level statements is mostly a matter of technical considerations.

In compiled languages, statically typed languages, it is necessary to create a complete list of top-level functions to be able to properly compile them. For compiled programs these functions may be exposed individually and called by external programs that may link to your bundle. Fundamentally your program will compile into a set of functions with maybe some related data, perhaps with also a entry point which is just another function and can also be called by external libraries.

On the other hand, in more dynamic interpreted languages functions may be created, destroyed, and modified on the fly. A function declaration is just another type of statement, and it won't exist until then. There is no real difference between the inside and outside the function, all code will be run one by one top to bottom. If functions are just expressions it makes sense to allow other expressions too where functions are allowed.

If you fall into neither of these categories, the choice is up to you. Allowing only functions at the top level can make type checking easier, but also adds more boilerplate.
---
### Answer by username_1 on 2023-05-24. Score: 3
## Boilerplate for small projects

Java has an infamously verbose “hello world” due to the amount of boilerplate required to run anything. Python and JS, on the other hand, both have one-liners.

## Imports with side effects

When you `require` a file in JS, all top-level code in that file is run, which can have side effects. Sometimes this is useful (e.g. a master test script can just `require` each individual test), but usually this is unwanted. Some languages, like Swift and C#, get around this by only allowing one file per project with top-level code.
> **Comments:**
> **username_5** (2023-05-24): Hello, world, is getting shorter in the next version of Java (not very smart, I'd say, if you read the relevant JEP)  
---
### Answer by username_4 on 2023-11-15. Score: 0
TLDR: Such constructs aren't supportable in all execution environments.

Many high-level language compilers don't generate executable programs directly, but instead produce object files which will then be fed to a linker in order to generate an executable. Some linkers may provide a mechanism by which multiple object files can contain code which should be run at program startup, without any of the object files knowing about each others' initialization code, but not all linkers support such things. A language which allows source files to include code which isn't in functions, and which should be run at program startup, would either be unusable with linkers that can't support such constructs, or would cause the range of constructs available to programmers to vary depending upon the linker used. Such compromises may be acceptable for some language designers, but many prefer to limit languages features to those that linkers can universally support.
---
