Skip to content

Instantly share code, notes, and snippets.

@LAK132
Last active February 4, 2026 07:35
Show Gist options
  • Select an option

  • Save LAK132/0d264549745e8196df1e632d5b518c37 to your computer and use it in GitHub Desktop.

Select an option

Save LAK132/0d264549745e8196df1e632d5b518c37 to your computer and use it in GitHub Desktop.

Revisions

  1. LAK132 revised this gist Jul 9, 2025. 1 changed file with 138 additions and 0 deletions.
    138 changes: 138 additions & 0 deletions result_statement_expression_try.c
    Original 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);
    }
    }
  2. LAK132 revised this gist Dec 3, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion results.c
    Original 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), boo, maybe_make_thing);
    map(result, Result(thing_t, bool), bool, maybe_make_thing);

    Result(thing_t, bool) flattened = flatten(maybe_thing, thing_t, bool);

  3. LAK132 revised this gist Dec 3, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion results.c
    Original 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##_##err##_t
    #define Result_EX(T, E) result_##T##_##E##_t
    #define Result(T, E) Result_EX(T, E)
    #define ResultDecl(T, E) \
    typedef struct \
  4. LAK132 created this gist Jun 11, 2021.
    130 changes: 130 additions & 0 deletions results.c
    Original 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);
    }
    }