Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
PavelVozenilek opened this issue Oct 3, 2017 · 2 comments
Closed
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.

Comments

@PavelVozenilek
Copy link

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(...);
}

@andrewrk
Copy link
Member

andrewrk commented Oct 3, 2017

This is not the best way to support multiple interfaces.

Precisely communicate intent.

@andrewrk andrewrk closed this as completed Oct 3, 2017
@andrewrk andrewrk added proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. rejected labels Oct 3, 2017
@andrewrk
Copy link
Member

andrewrk commented Oct 3, 2017

See #130

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

No branches or pull requests

2 participants