3 ms·
I've always found the rules quite simple, once you think of everything as expressions (and not lines): "." ends an expression in the shell. In modules, "." en
by mononcqc 17y ago
I've always found the rules quite simple, once you think of everything as expressions (and not lines):
"." ends an expression in the shell.
In modules, "." ends forms. Forms are module attributes and function declarations. Forms are technically not expressions as they don't return anything. This is why they are terminated in a different manner than the rest.
Given forms =/= expressions, It could be argued that the shell's use of "." is what's not standard here.
"," separates expressions:
C = A+B, D = A+C
Note that 'if ... end', 'case ... of ... end', 'begin ... end', 'fun() ... end' and 'try ... catch ... end' are all considered expressions as they return a single value. As an example, it's possible to do
Var = case ... of ... end
to get a single value out of it. As such, you might see conditional expressions followed by ",".
";" Has two roles: separating different function clauses:
fac(0) -> 1;
fac(N) -> N * fac(N-1).
And separating different branches of expressions like 'if ... end', 'case ... of ... end' etc.:
if X < 0 -> neg;
X > 0 -> pos;
X == 0 -> zero
end
It's probably the most confusing one because the last branch doesn't need to have the ";" following it: it separates them, not ends them. As such, you might encounter code written the following way, which is arguably more readable:
if X < 0 -> neg
; X > 0 -> pos
; X == 0 -> zero
end
This makes things a bit more explicit. Because function clauses contain expressions, you might see a 'case' construct followed by ";", too (and similarly for nested constructs like the aforementioned 'try ... catch ... end' and others).
So as you can see, "." is for Forms, and ",;" are for separating language constructs/expressions. This is why You can see an if expression's 'end' done the three following ways: 'end.', 'end,' and 'end;'. Depending on where the expression is, it will be followed by different stuff.
You need to see it more like a template you can fill in than "here, let me put an end to this line!":
head1(Args) [Guard] ->
Expression1,Exp2,...,ExpN;
head2(Args) [Guard] ->
Expression1,Exp2,...,ExpN;
headN(Args) [Guard] ->
Expression1,Exp2,...,ExpN.
I don't see the rules as complex; they make sense, but you need to get used to them. If you think about it, things like 'for(int i = 0; i >= x; i++){ ... }' (or even 'for(...);') have a weird syntax when compared to most other constructs in languages supporting them. We're just so used to them we don't mind them anymore.
- davidw 17y agoThey make sense once you get them, sure, but I still think that ';' or 'end' or {} are a lot easier.
- jerf 17y agoIt's actually not the strangeness that throws me any more; I've programmed in Erlang enough that I'm not spending much time thinking about it anymore. (I am that rare bird: Someone what has actually programmed Erlang professionally. :) ) But the copying and pasting bothers me. Also, to put it in a C context, when you do: if (condition) thing(); else other_thing(); you frequently want to put debugging code in the "thing()" clause, and so eventually many people (including me) adopt a style of always using the braces, after getting bitten a few time. Erlang basically mandates the lack of braces, so I'm always getting annoyed by adding a statement here or there, or twiddling a function definition. It's a constant low-level annoyance that never stops me from using it for what it is good for (because it is oh-so-good at it), but it doesn't have to be there.