#define CHECK_N(x, n, ...) n #define CHECK(...) CHECK_N(__VA_ARGS__, 0,) #define PROBE(x) x, 1, #define IS_PAREN(x) CHECK(IS_PAREN_PROBE x) #define IS_PAREN_PROBE(...) PROBE(~) #define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__) #define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__ #define COMPL(b) PRIMITIVE_CAT(COMPL_, b) #define COMPL_0 1 #define COMPL_1 0 #define IIF(c) PRIMITIVE_CAT(IIF_, c) #define IIF_0(t, ...) __VA_ARGS__ #define IIF_1(t, ...) t #define NOT(x) CHECK(PRIMITIVE_CAT(NOT_, x)) #define NOT_0 PROBE(~) #define BOOL(x) COMPL(NOT(x)) #define IF(c) IIF(BOOL(c)) #define EAT(...) #define EXPAND(...) __VA_ARGS__ #define WHEN(c) IF(c)(EXPAND, EAT) #define auto () // maybe don't do this in arbitrary code #define let(v, type) IF(NOT(IS_PAREN(type)))(typeof(type) v, __auto_type v) int main() { let(x, int) = 10; let(y, int*) = &x; let(z, auto) = 100; return *y; } int bar(let(x, int)) { return x + 1; } let(foo, int(*)(int)) = bar; let(baz, auto) = bar; let(boo, char[4096]);