16

I just stomped at a begin...end in Erlang's documentation (here), but it doesn't give some examples of how it is useful.

Looking here in StackOverflow I found two cases where people would be using begin...end, both in list comprehensions:

But I wonder if there are more of such uses.

Can anyone provide another scenario in which a begin...end is useful in Erlang?

Thanks

Community
  • 1
  • 1
Daniel
  • 21,933
  • 14
  • 72
  • 101
  • you can just use it to create quick code to evaluate and create the value you want. e.g. `T = {1,2,begin 1+2 end}.` will evalute `T={1,2,3}` – Muzaaya Joshua Nov 26 '13 at 11:11
  • @MuzaayaJoshua But your example works even without begin end. Can anyone give an example that actually requires using being end? Or are they like curly brackets? – Aus Oct 04 '17 at 08:45
  • @Aus check the answers below, there are examples that cannot be accomplished without begin...end – Daniel Oct 04 '17 at 14:52

4 Answers4

12

Macros, for example:

-define(M(A, B),
    begin
        C = foo(),
        bar(A, B, C)
    end).
P_A
  • 1,804
  • 1
  • 19
  • 33
  • 3
    Thanks @P_A. Some clarifications so others don't have to test what I just tested. A macro with more than one expression can be made without `begin...end`. But, if you are using that macro in a place where only one element is expected (like in `io:format`) then `begin...end` is the way to go. – Daniel Nov 21 '13 at 20:00
  • How is this better than -define(M(A, B), bar(A, B, foo())). ? – Lyn Headley Jan 19 '16 at 03:55
  • It's just an example to show how `begin...end` can be used – P_A Jan 19 '16 at 12:49
9

To evaluate a catch (always the same idea to have multiple expression reduced to one)

Res = (catch
    begin
        C = foo(Bar),
        io:format("evaluation of C ok~n"),
        D = bar(A, B, C)
     end),
Pascal
  • 13,977
  • 2
  • 24
  • 32
5

As previous answerers mentioned, this construct is used whenever you need to have multiple expressions but only one is allowed.

However, the majority of such cases would be considered a stinky style. I can remember only a few of places where a single expression is expected: an argument in a function call, catch expression, case of, try of and list comprehension. All of them except for list comprehension shouldn't be used with begin end construct because the variables are leaking to the outer scope probably causing the subsequent bindings to become matches.

List comprehension expression is different because it is transformed to a separate function with its own scope and no variable introduced in begin end leaks to the outer scope.

Dmitry Belyaev
  • 2,573
  • 12
  • 17
  • In which part of `try of` ? in each of the 3 segments of a `try...of...catch` we can put several instructions. – Daniel Nov 21 '13 at 21:45
  • Hmm, you're right. I thought only one expression is allowed in `try of ... catch ... end` expression. Actually this works fine: `try a = b, b of A -> A catch C:E -> {C,E} end.`. Thanks! – Dmitry Belyaev Nov 22 '13 at 06:40
  • @Aus Wrong in what? The answer proposes the only valid usage of `begin end` is in list comprehensions. And as `try of` allows multiple expressions `begin end` has even less applications even if you don't care about the quality of the code. – Dmitry Belyaev Oct 05 '17 at 00:19
  • @DmitryBelyaev In your answer you wrote "case of" takes a single expression, and MondKin said it does not. "case of" takes multiple true/false conditions as a single expression, but you cannot run an assignment statement for example before a true/false condition, see my answer below. What I wanted to say is that you are correct, however the definition of "expression" wasn't so clear. – Aus Oct 09 '17 at 16:14
2

According to erlang documentation is it block expression that evaluates each expression but returns only the last one.

See this example (not using block expression):

A = 1,
case A + 1 of
    3 ->
        ok;
    _->
        nop
end.

% returns ok

Now you can define A within the case argument using block expression:

case begin A = 1, A + 1 end of
    3 ->
        ok;
    _->
        nop
end.

%returns ok

That evaluates A = 1, then returns the result of A + 1.

Now we know that this will not work:

case A = 1, A + 1 of
    3 ->
        ok;
    _->
        nop
end.

% returns syntax error before: ','
Aus
  • 1,183
  • 11
  • 27