2
$\begingroup$

Some languages like C and C++ require defining the names before using them, though the definition could sometimes be only a header specifying something is a struct or function without the body. Some languages don't. And many interpreted languages are mixed, that you could refer to anything in the definition, but the code must be called after the referred entities are also defined completely.

What are the exact criteria for designing the syntax to make referring before definition possible? And is it possible to have a middle ground, that forward declarations are only required in the situations that it is absolutely necessary?

In the best case, function bodies are just strings, and definitions are scanned before evaluation, making this trivial. In the worst case, you could define new syntax in the code, which may change the position of the end of a function, making this obviously impossible. But where do they meet?

A special example is Bash, where functions are in the mixed way, as they are just called using their names as strings and there isn't a mechanism to track down where they are defined, but aliases must be defined before using in a function, because you could alias unpaired braces or other grouping constructs. It looks like a middle ground, but is greatly simplified because of the fact that Bash is not object oriented. In object oriented languages, object definitions may carry a syntax change from a class elsewhere.

$\endgroup$
2
  • 2
    $\begingroup$ The only real requirement is that your compiler does at least two passes over the source code. In that case, you can find all declarations on the first pass and then use them by name in the second pass. The order that they appear in the source code only matters if you have to find declarations and also do name resolution in the same pass. $\endgroup$
    – kaya3
    Commented Jul 27, 2023 at 23:06
  • 1
    $\begingroup$ @kaya3-supportthestrike I think aliases in bash could not be referred before definition in any implementation, because you could alias x={. You could get similar things if you are going to support two different kind of regexes using different escapes, in grammars like JavaScript, and only distinguish them by the function call. More practically, in C++, the keyword typename is sometimes required in random places in templates even with SFINAE. I wonder why it is the case. $\endgroup$
    – user23013
    Commented Jul 27, 2023 at 23:21

1 Answer 1

3
$\begingroup$

Multi passes

Forward declarations are a specific requirement of one pass compilation process. So to not have to forward declare anything, your language is expected to have two or more passes on code or AST to resolve pending names.

C and C++ are special in this case because any previous typedef may change the parsing of the following expression. Languages with keywords to declare types and functions don't have this extra requirement.

Dynamic languages without type checking and dispatch based purely by names don't need more than one pass because any dispatch occurs by consulting what is basically a global dictionary of names.

But type checking languages, dynamic or static, will need more passes for any reference not declared before use.

$\endgroup$
3
  • $\begingroup$ "Languages with keywords to declare types and functions", did you mean different keywords to declare the two? Of course it would require multiple passes. But I'm also interested in the part that may make C and C++ problematic even with multiple passes. $\endgroup$
    – user23013
    Commented Jul 27, 2023 at 23:28
  • $\begingroup$ About keywords, it depends. For example, PHP have both class and function, but Java and C# have only class. For the C/C++ case, I linked another answer with a detailed explanation. $\endgroup$ Commented Jul 27, 2023 at 23:47
  • 1
    $\begingroup$ The linked answer has some examples, but the problem in C and C++ is specifically that the grammar relies on knowing whether an identifier is a type or a value in several places. So even if you try to do two passes (one to collect the names and another to resolve the references) you will not be able to produce an unambiguous syntax tree until the second pass- and in some cases that means you will not even have an accurate set of names after the first pass. $\endgroup$
    – rpjohnst
    Commented Jul 28, 2023 at 13:04

You must log in to answer this question.

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