Skip to content

Proposal: compile time decision based on ability to compile a snippet #524

@PavelVozenilek

Description

@PavelVozenilek

Right now Zig allows to make compile time decision on a type/literal value, like:

fn max(comptime T: type, a: T, b: T) -> T {
    if (T == bool) {
        return a or b;
    } else if (a > b) {
        return a;
    } else {
        return b;
    }
}

This is rather limited (one can check types for equality, question basic types, ask if cast is possible and not much more) and does not cover many real problems.

E.g. there are two variants of allocators:

  1. traditional one with malloc/realloc/free,
  2. other without realloc and with size parameter for free (this has some advantages).

And one would like to make a library which is able to use both allocator variants, easily.


My proposal: allow compile time decision based on ability to compile (or not) a snippet:


fun foo(comptime Allocator : type, a : &Allocator)
{
  if-compiles {
    a.realloc(null, 10);  /// compiles only with first allocator variant
  } => {
      ...  /// runtime code using variant 1
  } elif-compiles {
      a.free(null, 10);  /// compiles only with second allocator variant
   } => {
      ...  /// runtime code using variant 2
   }  else {
    @compileError("");
  }
}


Notes:

  1. If a provided snippet compiles then its associated block is selected.
  2. The snippet itself gets discarded, nothing is executed.
  3. Trivial syntax errors (like unbalanced parenthesis) stop compilation, always.
  4. There could be a "compiles-switch" which verifies that one and exactly one branch compiles. This would eliminate problems after new alternative is added/removed and one forgets to update some code.
  5. I took inspiration for this from one feature of Nim language.

Compile time switch example:

compiles-switch { /// one and only one arm must work
  { a.realloc(null, 10) } => ...
  { a.free(null, 10) } => ...
}


Even shorter syntax is possible for conditional compilation:

// If this compiles use it, if it doesn't compile ignore it
??? {
   x = a.realloc(...);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    proposalThis issue suggests modifications. If it also has the "accepted" label then it is planned.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions