Defer in Erlang

In Erlang, there’s no direct equivalent to the defer keyword. However, we can achieve similar functionality using the try-after construct. This ensures that certain operations are performed, even if an exception is raised.

Let’s see how we can implement a similar file operation example in Erlang:

-module(defer_example).
-export([main/0]).

main() ->
    FileName = "/tmp/defer.txt",
    {ok, File} = create_file(FileName),
    try
        write_file(File)
    after
        close_file(File)
    end.

create_file(Path) ->
    io:format("creating~n"),
    case file:open(Path, [write]) of
        {ok, File} -> {ok, File};
        {error, Reason} -> error(Reason)
    end.

write_file(File) ->
    io:format("writing~n"),
    file:write(File, "data\n").

close_file(File) ->
    io:format("closing~n"),
    case file:close(File) of
        ok -> ok;
        {error, Reason} ->
            io:format(standard_error, "error: ~p~n", [Reason]),
            halt(1)
    end.

In this Erlang version:

  1. We define a main/0 function that serves as the entry point of our program.

  2. We use a try-after block to ensure that the file is closed, regardless of whether an exception occurs during the write operation.

  3. The create_file/1 function opens a file for writing and returns the file descriptor.

  4. The write_file/1 function writes data to the file.

  5. The close_file/1 function closes the file and handles any potential errors.

To run the program, save it as defer_example.erl and use the Erlang shell:

$ erl
1> c(defer_example).
{ok,defer_example}
2> defer_example:main().
creating
writing
closing
ok

This example demonstrates how to ensure proper resource cleanup in Erlang, similar to the defer functionality in other languages. The try-after construct guarantees that the file will be closed, even if an exception occurs during the write operation.