Contents

Reserved names — Mere top-level fn names and C codegen collisions

Mere's C codegen emits top-level fns directly as C functions. As a result, if a top-level let / let rec binding name collides with an existing function in libc / libm on macOS / Linux or with a C language keyword, codegen succeeds but clang / gcc then fail with a compile error.

The interp / LLVM / Wasm backends are unaffected (so a program that runs in interp can fail in C codegen). Because this is easy to miss, the Phase 38.A3 linter issues a warning at parse time. This document is the full list of reserved names plus avoidance patterns.

TL;DR: writing a top-level binding that collides with any name in the table below produces a warning + C compile error at codegen time. Avoid it via a prefix (`m_` / `mere_`) / suffix (`_` / `_v`) / verb phrase (`run_*` / `*_list`).

1. Collision list (~110 names)

The implementation is in `lib/pipeline.ml:42` under reserved_c_names. Defining a top-level binding with one of these names triggers a Phase 38.A3 linter warning.

1.1 C keywords (~30)

short / long / int / char / float / double / signed / unsigned / register / static / auto / extern / const / volatile / restrict / inline / goto / return / break / continue / switch / case / default / do / while / for / if / else / sizeof / typedef / struct / union / enum / void

Most likely to hit: `case` (often when writing match-arm helpers), and `default` / `type` / `return` (common in DSL-style naming).

1.2 stdlib.h (libc, ~22)

div / ldiv / exit / abort / atexit / atof / atoi / atol / free / malloc / calloc / realloc / system / getenv / setenv / putenv / unsetenv / rand / srand / abs / labs / qsort / bsearch / mergesort

Most likely to hit: `div` (rationals / matrices / GCD-style code), `rand` (random helpers), `abs` (people often shadow the builtin absolute-value function).

1.3 math.h (libm, ~17)

pow / sqrt / sin / cos / tan / asin / acos / atan / atan2 / exp / log / log10 / log2 / ceil / floor / round / trunc / fabs / fmod / hypot / sinh / cosh / tanh

These are also defined as Mere builtins with the same names (e.g. pow / sqrt). A same-named user top-level binding shadows and collides. Avoid with mere_pow / power_int etc.

1.4 time.h (libc, ~9)

time / clock / ctime / asctime / gmtime / localtime / mktime / difftime / strftime

Most likely to hit: `time` (shadowing the builtin time-fetching function).

1.5 POSIX I/O (~18)

read / write / open / close / lseek / stat / fstat / fopen / fclose / fread / fwrite / fseek / ftell / rewind / printf / scanf / fprintf / fscanf / sprintf / sscanf / puts / gets / fputs / fgets / putchar / getchar

Most likely to hit: `read` / `write` (when writing file-I/O wrappers); `printf` (debug helpers).

1.6 misc libc (~15)

strlen / strcpy / strncpy / strcat / strncat / strcmp / strncmp / strchr / strrchr / strstr / strdup / strerror / memcpy / memmove / memset / memcmp / memchr / `main`

main is especially important — C reserves it as the execution entry point. A Mere top-level expression automatically becomes the main function, so a user let main = ... is always a conflict.

2. Avoidance patterns (3)

PatternExample (collision name → safe name)Use case
Suffixcasecase_ / case_v / run_caseOne-character addition suffices. case_v is the example the linter message suggests (no deep meaning)
Prefixdivdivi / mere_div; powpower_int / m_powCarries a namespacing nuance; the mere_ prefix is recommended for contrib libs
Verb phrasemergesortsort_list; powpower_ofThe most natural-language-readable; recommended for lib APIs

Recommended approach:

3. See also

4. Future extensions (DEFERRED)

StageContent
A. Auto-rename suggestionsThe linter would suggest name-specific replacements like "powpower" or "casecase_" (currently only generic _ / m_ / _v are suggested)
B. NamespacingAllow same-named top-level bindings inside modules (currently M.case after module rewrite is still emitted as a C function, so it's blocked)

Both are issue-driven work for after public release.