aboutsummaryrefslogtreecommitdiffhomepage
path: root/notes/compile_time_execution.txt
blob: 47446cb49c0c04effb43c365e2e8ac350965e1be (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

Compile-time execution and alternatives
=======================================

Common alternatives
-------------------

* Code generation (somewhat ugly)
* Reflection (ugly, and requires RTTI)
* Serialized data generation, that is then read by the compiler.
* A pre-processor
* Not so common alternative:
    - Manually write the "full" code, but have a source code
      checker that checks that the "full" code is correct.

Use cases
---------

1. Generating data / data structures at compile time
2. Generating interfaces from external definitions
3. Generating code in function bodies
4. Inlining functions
5. Generating algorithms
6. Generating tests
7. Including information about the source
8. Avoiding duplication (e.g. including something as both a string and an
   identifier)
9. Avoiding or detecting programming errors (e.g. static_assert)

Point 2 is really tricky when it comes to SLUL, and it might be undesirable,
as it makes the interface dynamic rather than static (and hence much trickier
to version). Instead, it might be better to check that the interface matches
its external definition, rather than trying to generate it from the definition.

Point 7 is easy to abuse, and could make code hard to refactor (since code
begins to depend on source filenames and line numbers). It could also reduce
performance.

Avoiding CTE
------------

* Advanced constant evaluation can solve a very limited part of 1, 3 and 4.
* Generics and "pipe functions" can partly handle 5.

Syntax test
-----------

    macro min(comparable a, comparable b) = a < b ? a : b

    macro .min(T a, T b) -> T
    {
        if a < b return a
        else return b
    }