Why I should use `maybe` instead of `try-catch`?

Hi Everyone,

I just started learning Erlang, I using Erlang/OTP 26. I learn to use maybe syntax. And my feelings is that it’s the same as feel when using try-catch. So the questions is

  1. Why we should use maybe syntax?
  2. What’s the main benefit of maybe syntax?
  3. Is it only me alone feels maybe feels like try-catch ?

Please enlightment

Thank you :slight_smile:

2 Likes

you can find good explanation and examples in the original EEP for maybe: Eep 0049 - Erlang/OTP. For me the reduce-nesting is a big advantage.

3 Likes

OMG!
After reading your reference, and I try step by step and try to feels it.
And Yes! maybe saves me from nested-condition-block-hell. Wow!

And after understanding the benefit of maybe , then I implement it in my work. Here we go

-module(repository_voucher_usage).
-feature(maybe_expr, enable).
-export([get_data/1]).

-spec get_data(string()) -> {list(tuple()), list(tuple())} | empty.

get_data(Voucher) ->
    QueryVoucherUsage = <<"
    SELECT
    vc.`id` voucher_id
    ,vc.`voucher_code`
    ,vc.`voucher_category_id`
    ,vc.`site_id`
    ,vc.`max_device`
    ,vc.`is_sold`
    ,vc_use.id voucher_usage_id
    ,vc_use.`start_at` vcr_use_start_at
    ,vc_use.`end_at` vcr_use_end_at
    ,vc_cat.`category_name`
    ,vc_cat.`price_basic` vcr_price_basic
    ,vc_cat.`duration_value` vcr_duration_value
    ,vc_cat.`duration_unit` vcr_duration_unit
    ,sites.site_name
    ,sites.address site_address
    ,sites.selling_price_percentage site_selling_price_percentage
    FROM voucher_usages vc_use
    LEFT JOIN vouchers vc ON vc_use.voucher_id  = vc.id
    LEFT JOIN voucher_categories vc_cat ON vc.voucher_category_id  = vc_cat.id
    LEFT JOIN sites ON vc.site_id = sites.id
    WHERE vc_use.deleted_at IS NULL
    AND vc.voucher_code = ?
    LIMIT 1
    ">>,

    QueryVoucherUsageDevice = <<"
    SELECT
    vc_use_dev.mac
    ,vc_use_dev.created_at
    FROM voucher_usage_devices vc_use_dev
    WHERE vc_use_dev.deleted_at IS NULL
    AND vc_use_dev.voucher_usage_id = ?
    ">>,

    VoucherUsage =
    maybe
        {ok, Cols, Rows} ?= database_mysql:query(QueryVoucherUsage, [Voucher]),
        true ?= length(Rows) > 0,
        [Row | _T] = Rows,
        lists:zip(Cols, Row)
    else
        false -> empty
    end,

    ListOfVoucherUsageDevice =
    maybe
        true ?= is_list(VoucherUsage) andalso length(VoucherUsage) > 0,
        VoucherUsageId = proplists:get_value(<<"voucher_usage_id">>, VoucherUsage),
        {ok, Cols00, Rows00} = database_mysql:query(QueryVoucherUsageDevice, [VoucherUsageId]),
        true ?= length(Rows00) > 0,
        [lists:zip(Cols00, Row00) || Row00 <- Rows00]
    else
        false -> []
    end,

    maybe
        true ?= is_list(VoucherUsage),
        {VoucherUsage, ListOfVoucherUsageDevice}
    else
        false -> empty
    end.

It’s so awesome!

I think maybe expression / syntax will makes me addicted :laughing:

2 Likes