Mikael Pettersson pointed out that this really has less to do with immutable local variables and more to do with the lack of a let expression. That was insightful, and since a let expression can be considered syntactic sugar for a lambda expression, I realized that a parse transform could provide let like functionality. Let is a reserved keyword in Erlang so I used lyet instead.
Essentially the parse transform rewrites
lyet:lyet (A = B, C)as
(fun (A) -> C end) (B)so the above code could be rewritten as
Result = lyet:lyet (
% Take away underscore and replace with hyphen
MO = re:replace(MO, "_", "-", [{return, list}, global]),
MO = toupper(MO),
% Replace zeros
MO = re:replace(MO,
"RX0",
"RXO",
[{return, list}, global]),
% Insert hyphen if missing
case re:run(MO, "-", [{capture, none}]) of
nomatch ->
insert_hyphen(MO);
match ->
MO
end),
You must provide at least one argument to lyet:lyet. All but the last argument to lyet:lyet must be an assignment, and the last argument has to be a single expression (but you can use begin and end for a block of expressions inside the lyet). As you can see above, you can reuse a variable name across the assignment arguments to lyet:lyet. You can even use lyet:lyet on the right hand side of the assignments, or as part of the expression argument. Some examples of usage are present in the unit test.
Update: per Ulf's suggestion, the parse transform also recognizes the local call let_ in addition to the remote call lyet:lyet. It definitely looks nicer with let_.
The software is available on Google code.
Since it's a parse transform anyway, you don't have to make it a remote call - as long as you pick a function name that is not likely to be taken.
ReplyDeleteHow about let_ ?
testtwo (X) ->
let_ (X = g (X),
let_ (X = h (X),
let_ (X = l (X),
m (X)
)
)
).
If it would happen to clash with some existing function, you could provide a remote call as a backup.
That's a great suggestion, I will incorporate it.
ReplyDelete