# Function called before definition

**URL:** <https://forum.crystal-lang.org/t/function-called-before-definition/3424>\
**Category:** Help & Support\
**Created:** [June 25, 2021, 2:47am UTC](https://forum.crystal-lang.org/t/function-called-before-definition/3424 "2021-06-25T02:47:11Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![vgramkris](https://avatars.discourse-cdn.com/v4/letter/v/7ea924/32.png) [@vgramkris](https://forum.crystal-lang.org/u/vgramkris)\
**Post date:** [June 25, 2021, 2:47am UTC](https://forum.crystal-lang.org/t/function-called-before-definition/3424/1 "2021-06-25T02:47:12Z")

</div>

When a function is called even before it is defined then there is no error reported. But if a macro or a variable is referred before its definition then I get errors “macro ‘func’ must be defined before this point but is defined later” and “undefined local variable or method ‘func’ for top-level” respectively as expected. Crystal version 1.0.0 & LLVM 10.0.0

```auto
  1 puts func
  2 def func
  3 "function func"
  4 end

```

outputs, `function func`

---

<div class="post-metadata">

**Author:** ![drhuffman12](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/drhuffman12/32/715_2.png) [@drhuffman12](https://forum.crystal-lang.org/u/drhuffman12)\
**Post date:** [June 25, 2021, 2:52am UTC](https://forum.crystal-lang.org/t/function-called-before-definition/3424/2 "2021-06-25T02:52:51Z")

</div>

Interesting question. Maybe this has to do with the sequence of compiling various types of code; kinda like the scope of a variable, but for methods, macros, etc.

---

<div class="post-metadata">

**Author:** ![henrikac](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/henrikac/32/3079_2.png) [@henrikac](https://forum.crystal-lang.org/u/henrikac)\
**Post date:** [June 25, 2021, 8:15am UTC](https://forum.crystal-lang.org/t/function-called-before-definition/3424/3 "2021-06-25T08:15:08Z")

</div>

_Macros are methods that receive AST nodes at **compile-time** and produce code that is pasted into a program_ [1](https://crystal-lang.org/reference/syntax_and_semantics/macros/index.html).

My guess would be that calling a method before it is defined is fine because the code it is evaluated at runtime but macro-stuff happens at compile-time (I could be wrong though).

I hope this make sense? :)

---

<div class="post-metadata">

**Author:** ![straight-shoota](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/straight-shoota/32/36_2.png) [@straight-shoota](https://forum.crystal-lang.org/u/straight-shoota)\
**Post date:** [June 25, 2021, 8:37am UTC](https://forum.crystal-lang.org/t/function-called-before-definition/3424/4 "2021-06-25T08:37:25Z")

</div>

Yes, that’s more or less correct. In a first pass, the compiler processes all the types and methods (without their body) in the program (`TopLevelVisitor`). Only after that, it starts processing top-level code (and the code inside methods). So a that point, it already knows which types and methods are available, regardless of the order of their definition relative to the code that uses them.

Variable definitions and reads are expressions and always execute in order. Hence you can’t read from a variable before it’s defined.

The thing with macros is a bit more complex. They are called like methods. From a syntactical point of view, there’s no difference between calling a method and calling macro. So it’s impossible to tell them apart. The compiler just checks if a macro by that name exists and if yes, treats it as a macro call.

Macro calls on the top level can define types, methods etc. - or even more macros. This all happens in the first stage (`TopLevelVisitor`) and can have transitive dependencies (a macro defining another macro, for example). It’s impossible to know about all macro definitions in the entire program before expanding all macros. That creates a chicken and egg problem, and it is solved such that macros unlike methods are only visible after they are defined.

---

<div class="post-metadata">

**Author:** ![vgramkris](https://avatars.discourse-cdn.com/v4/letter/v/7ea924/32.png) [@vgramkris](https://forum.crystal-lang.org/u/vgramkris)\
**Post date:** [June 25, 2021, 1:59pm UTC](https://forum.crystal-lang.org/t/function-called-before-definition/3424/5 "2021-06-25T13:59:17Z")

</div>

@straight-shoota Thanks for the detailed answer. This makes sense.
