Last active
February 4, 2026 07:35
-
-
Save LAK132/0d264549745e8196df1e632d5b518c37 to your computer and use it in GitHub Desktop.
Revisions
-
LAK132 revised this gist
Jul 9, 2025 . 1 changed file with 138 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,138 @@ #ifndef __cplusplus # define decltype typeof # include <stdbool.h> #endif #include <assert.h> #include <stdlib.h> #include <stdio.h> #define TOKEN_CONCAT_EX(x, y) x##y #define TOKEN_CONCAT(x, y) TOKEN_CONCAT_EX(x, y) #define UNIQUIFY(x) TOKEN_CONCAT(x, __LINE__) #define Result_EX(T, E) result_##T##_##E##_t #define Result(T, E) Result_EX(T, E) #define ResultDecl(T, E) \ typedef struct \ { \ bool _is_ok; \ union \ { \ T _ok; \ E _err; \ }; \ } Result(T, E) #define Ok(V, T, E) \ ((Result(T, E)){ \ ._is_ok = true, \ ._ok = V, \ }) #define Err(V, T, E) \ ((Result(T, E)){ \ ._is_ok = false, \ ._err = V, \ }) #define is_ok(V) (V._is_ok) #define is_err(V) (!(V._is_ok)) #define if_let_Ok(I, V) \ if (is_ok(V)) \ for (bool UNIQUIFY(once) = true; UNIQUIFY(once);) \ for (decltype(V._ok) I = V._ok; UNIQUIFY(once); UNIQUIFY(once) = false) #define if_let_Err(I, V) \ if (is_err(V)) \ for (bool UNIQUIFY(once) = true; UNIQUIFY(once);) \ for (decltype(V._err) I = V._err; UNIQUIFY(once); UNIQUIFY(once) = false) #define unwrap(V) ((is_ok(V) ? (void)0 : abort()), V._ok) #define unwrap_err(V) ((is_err(V) ? (void)0 : abort()), V._err) #define get_ok(V) (is_ok(V) ? &(V._ok) : nullptr) #define get_err(V) (is_err(V) ? &(V._err) : nullptr) #define map(V, T, E, F) (is_ok(V) ? Ok(F(V._ok), T, E) : Err(V._err, T, E)) #define map_err(V, T, E, F) \ (is_err(V) ? Ok(V._ok, T, E) : Err(F(V._err), T, E)) #define and_then(V, T, E, F) (is_ok(V) ? F(V._ok) : Err(V._err, T, E)) #define or_else(V, T, E, F) (is_ok(V) ? Ok(V._ok, T, E) : F(V._err)) #define flatten(V, T, E) \ (is_ok(V) ? (is_ok(V._ok) ? Ok(V._ok._ok, T, E) : Err(V._ok._err, T, E)) \ : Err(V._err, T, E)) #define _try(V, T, E) ({ if (is_err(V)) return Err(V._err, T, E); V._ok; }) typedef struct { int val; } thing_t; ResultDecl(int, bool); ResultDecl(thing_t, bool); ResultDecl(Result(thing_t, bool), bool); thing_t make_thing(int v) { return (thing_t){.val = v}; } Result(thing_t, bool) maybe_make_thing(int v) { if (v % 200 == 0) return Err(v == 200, thing_t, bool); else return Ok(make_thing(v), thing_t, bool); } Result(int, bool) test(bool v, int i) { if (v || i == 0) return Err(v, int, bool); else return Ok(i, int, bool); } Result(int, bool) test_try(bool v, int i) { int j = _try(test(v, i), int, bool); return Ok(j, int, bool); } int main() { int input1, input2; fscanf(stdin, "%d %d", &input1, &input2); Result(int, bool) result = test_try(input1 != 20, input2); if_let_Ok(ok, result) { fprintf(stdout, "%d\n", ok); } else if_let_Err(err, result) { fprintf(stderr, "%s\n", err ? "true" : "false"); } Result(thing_t, bool) thing = map(result, thing_t, bool, make_thing); if_let_Ok(ok, thing) { fprintf(stdout, "we got a thing %d\n", ok.val); } Result(Result(thing_t, bool), bool) maybe_thing = map(result, Result(thing_t, bool), bool, maybe_make_thing); Result(thing_t, bool) flattened = flatten(maybe_thing, thing_t, bool); if_let_Ok(ok, flattened) { fprintf(stdout, "we got a flattened thing %d\n", ok.val); } Result(thing_t, bool) and_thend = and_then(result, thing_t, bool, maybe_make_thing); if_let_Ok(ok, and_thend) { fprintf(stdout, "we got an and_then'd thing %d\n", ok.val); } } -
LAK132 revised this gist
Dec 3, 2022 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -111,7 +111,7 @@ int main() if_let_Ok(ok, thing) { fprintf(stdout, "we got a thing %d\n", ok.val); } Result(Result(thing_t, bool), bool) maybe_thing = map(result, Result(thing_t, bool), bool, maybe_make_thing); Result(thing_t, bool) flattened = flatten(maybe_thing, thing_t, bool); -
LAK132 revised this gist
Dec 3, 2022 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -10,7 +10,7 @@ #define TOKEN_CONCAT(x, y) TOKEN_CONCAT_EX(x, y) #define UNIQUIFY(x) TOKEN_CONCAT(x, __LINE__) #define Result_EX(T, E) result_##T##_##E##_t #define Result(T, E) Result_EX(T, E) #define ResultDecl(T, E) \ typedef struct \ -
LAK132 created this gist
Jun 11, 2021 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,130 @@ #ifndef __cplusplus # define decltype typeof # include <stdbool.h> #endif #include <assert.h> #include <stdlib.h> #include <stdio.h> #define TOKEN_CONCAT_EX(x, y) x##y #define TOKEN_CONCAT(x, y) TOKEN_CONCAT_EX(x, y) #define UNIQUIFY(x) TOKEN_CONCAT(x, __LINE__) #define Result_EX(T, E) result_##T##_##err##_t #define Result(T, E) Result_EX(T, E) #define ResultDecl(T, E) \ typedef struct \ { \ bool _is_ok; \ union \ { \ T _ok; \ E _err; \ }; \ } Result(T, E) #define Ok(V, T, E) \ ((Result(T, E)){ \ ._is_ok = true, \ ._ok = V, \ }) #define Err(V, T, E) \ ((Result(T, E)){ \ ._is_ok = false, \ ._err = V, \ }) #define is_ok(V) (V._is_ok) #define is_err(V) (!(V._is_ok)) #define if_let_Ok(I, V) \ if (is_ok(V)) \ for (bool UNIQUIFY(once) = true; UNIQUIFY(once);) \ for (decltype(V._ok) I = V._ok; UNIQUIFY(once); UNIQUIFY(once) = false) #define if_let_Err(I, V) \ if (is_err(V)) \ for (bool UNIQUIFY(once) = true; UNIQUIFY(once);) \ for (decltype(V._err) I = V._err; UNIQUIFY(once); UNIQUIFY(once) = false) #define unwrap(V) ((is_ok(V) ? (void)0 : abort()), V._ok) #define unwrap_err(V) ((is_err(V) ? (void)0 : abort()), V._err) #define get_ok(V) (is_ok(V) ? &(V._ok) : nullptr) #define get_err(V) (is_err(V) ? &(V._err) : nullptr) #define map(V, T, E, F) (is_ok(V) ? Ok(F(V._ok), T, E) : Err(V._err, T, E)) #define map_err(V, T, E, F) \ (is_err(V) ? Ok(V._ok, T, E) : Err(F(V._err), T, E)) #define and_then(V, T, E, F) (is_ok(V) ? F(V._ok) : Err(V._err, T, E)) #define or_else(V, T, E, F) (is_ok(V) ? Ok(V._ok, T, E) : F(V._err)) #define flatten(V, T, E) \ (is_ok(V) ? (is_ok(V._ok) ? Ok(V._ok._ok, T, E) : Err(V._ok._err, T, E)) \ : Err(V._err, T, E)) typedef struct { int val; } thing_t; ResultDecl(int, bool); ResultDecl(thing_t, bool); ResultDecl(Result(thing_t, bool), bool); thing_t make_thing(int v) { return (thing_t){.val = v}; } Result(thing_t, bool) maybe_make_thing(int v) { if (v % 200 == 0) return Err(v == 200, thing_t, bool); else return Ok(make_thing(v), thing_t, bool); } Result(int, bool) test(bool v, int i) { if (v || i == 0) return Err(v, int, bool); else return Ok(i, int, bool); } int main() { int input1, input2; fscanf(stdin, "%d %d", &input1, &input2); Result(int, bool) result = test(input1 != 20, input2); if_let_Ok(ok, result) { fprintf(stdout, "%d\n", ok); } else if_let_Err(err, result) { fprintf(stderr, "%s\n", err ? "true" : "false"); } Result(thing_t, bool) thing = map(result, thing_t, bool, make_thing); if_let_Ok(ok, thing) { fprintf(stdout, "we got a thing %d\n", ok.val); } Result(Result(thing_t, bool), bool) maybe_thing = map(result, Result(thing_t, bool), boo, maybe_make_thing); Result(thing_t, bool) flattened = flatten(maybe_thing, thing_t, bool); if_let_Ok(ok, flattened) { fprintf(stdout, "we got a flattened thing %d\n", ok.val); } Result(thing_t, bool) and_thend = and_then(result, thing_t, bool, maybe_make_thing); if_let_Ok(ok, and_thend) { fprintf(stdout, "we got an and_then'd thing %d\n", ok.val); } }