2
$\begingroup$

Most of the popular programming languages I know of either require or strongly encourage import statements to be at the top of the file, before any of the declarations and content of the file itself. Kotlin has a special error message stating "imports are only allowed at the top of a file", and Java won't even parse an import after a class declaration. Some languages, like Python, don't outright require it, but it's strongly encouraged and most linters will flag violations.

Now, if your language is mucking with the parser, I understand. If you're a self-modifying Lisp dialect, then in order to meaningfully parse the rest of the file you need to know what's in scope before reading it. If you're a language with an emphasis on reflection, then import isn't just a scoping tool; it's essentially a function call in itself and can carry side effects, so having it run first makes sense.

My question is in languages where that's not the case. It seems to be a near-universal law of programming languages that imports go first, then everything else.

In my mind, putting the imports at the end would actually make a lot more sense. A scientific paper starts with the abstract, then the contents of the paper, and at the end we have the bibliography, which cites all of the terms and prior results we use. Following this analogy, the "abstract" is a module-level comment describing what we're about to see. Then the "paper contents" is the actual declarations (functions, classes, etc.), and finally the "bibliography" is, of course, our imports, where we inform the programmer / compiler / interpreter of what all of the names we used actually mean in the broader context. In my mind, the set of imported names is one of the most boring parts of your source code, so putting it at the top seems counterproductive.

Are there any languages which have tried to put the import declarations for a file somewhere else? What are the compelling advantages to having imports listed at the very top of the file?

$\endgroup$
5
  • 3
    $\begingroup$ One difference is that papers have in-text citations. In languages like Java and C#, import statements aren't needed if you use fully qualified names; rather, the whole point of imports in those languages is to avoid qualifying them. $\endgroup$
    – Bbrk24
    Commented Nov 27, 2023 at 2:41
  • 1
    $\begingroup$ Swift programmers put import at the top (partly by convention, partly because that's what auto-import does), but to my surprise Swift actually does allow imports at the bottom (example). $\endgroup$
    – Bbrk24
    Commented Nov 27, 2023 at 2:43
  • 3
    $\begingroup$ Python import statements fall decidedly into the "essentially a function call in itself and can carry side effects" bucket, but it's worth noting that being a normal kind of statement also means they don't have to be at the very top of the program--they just have to be in the right scope and run at the right time to bind what you want from them. $\endgroup$ Commented Nov 27, 2023 at 3:24
  • 10
    $\begingroup$ I don't agree with this characterisation of a paper structure: it (should) start by establishing the framework it will be working with, which seems exactly analogous to indicating which modules you'll be using. It's clearly not something that matters semantically for most languages, but the convention seems obvious (although the history is probably more about single-pass compilation than design). Are you interested in the historical context of this norm or present-day rationales? $\endgroup$
    – Michael Homer
    Commented Nov 27, 2023 at 3:57
  • $\begingroup$ An answer the answer doesn't touch on is scope: C-style imports were raw file inclusion, and declarations had to be referenced in order, so #includes had to go at the top. This carried over as an influence to most languages with a more proper import system. Languages with somewhat of a module system ex. OCaml, Rust, typically do not necessitate top-level imports and it's common to open / use modules within function bodies and the like. $\endgroup$
    – apropos
    Commented Nov 27, 2023 at 21:35

1 Answer 1

6
$\begingroup$

Now, if your language is mucking with the parser, I understand. If you're a self-modifying Lisp dialect, then in order to meaningfully parse the rest of the file you need to know what's in scope before reading it. If you're a language with an emphasis on reflection, then import isn't just a scoping tool; it's essentially a function call in itself and can carry side effects, so having it run first makes sense.

My question is in languages where that's not the case. It seems to be a near-universal law of programming languages that imports go first, then everything else.

Because human readers of the code must also parse it, even if much less formally.

Putting the imports at the top allows anyone who is reading the code to be warned that the following code should be understood in the context of that import. Even when imports don't fundamentally change the syntactic interpretation of the code or anything like that - even if they only define symbols - it will be much easier for a human reader to understand what is going on, if some explanation for a symbol has been seen before the code that actually uses that symbol. Even without seeing an actual calculation or definition, knowing "oh, foo will be defined in the barlib" is an important courtesy to the reader.

It is the same idea that statically typed languages with manifest typing have, when they expect variable declarations to appear at the top of a scope: the syntax ensures that the type declaration in particular is at the top of the scope, and therefore that information is presented before the code that cares about the type.

$\endgroup$
4
  • 2
    $\begingroup$ Since OP mentioned Python as an example where this isn't necessary, but encouraged, the reason in this answer is also why statements like from foo import * is discouraged: you lose this benefit of understanding where a symbol came from with statements like those. $\endgroup$
    – muru
    Commented Nov 27, 2023 at 16:40
  • 2
    $\begingroup$ Do you read imports top to bottom? I don't. I only check the imports section when I want to know where a symbol came from, usually so I can find its definition. $\endgroup$ Commented Nov 27, 2023 at 17:46
  • $\begingroup$ @user253751 That sounds like the basis of an alternate explanation that deserves a separate answer. - Oh, the question was closed? Hmm, I don't think I agree with the rationale this time, although I understand it. $\endgroup$ Commented Nov 27, 2023 at 18:00
  • $\begingroup$ Last time I checked only C (before C99 I think) required variables to be at the top of a scope $\endgroup$
    – Seggan
    Commented Nov 27, 2023 at 18:26

Not the answer you're looking for? Browse other questions tagged .