[erlang-questions] Simple Erlang Recommendation (last returned value)

Alain O'Dea <>
Sun Jul 27 16:47:06 CEST 2008


On 27-Jul-08, at 6:26 AM,  wrote:

> On Sat, 26 Jul 2008, Alain O'Dea wrote:
>
>> On 26-Jul-08, at 6:47 PM, James Hague wrote:
>>
>>>> Imagine this:
>>>>
>>>> X = tl(L),
>>>> ... many messy lines ...
>>>> *X = tl(X),
>>>> ... another many lines ...
>>>> *X = tl(X),
>>>> ... another many almost unreadable messy lines ...
>>>> sensitive_usage(X), % <--- buggy X value observed here
>>>>
>>>> And my question is, where Value of X came from? It goes from L, but
>>>> how long
>>>> it take and how many errors you can do when you will investigate?
>>>
>>> It's just as bad when there's code like this:
>>>
>>> T2 = something(T),
>>> T3 = something(T2),
>>> T4 = something(T3),
>>> T5 = something(T4),
>>> T6 = something(T5)
>>>
>>> You may laugh at that code, but it's hardly uncommon, even in code
>>> written by experienced programmers.  It's very easy to accidentally
>>> use T4 in a spot when you meant T3, or to have to renumber things  
>>> and
>>> make a mistake.
>>>
>>> Please note that I am not arguing for changes in Erlang.  I truly am
>>> not.  But I can understand why this request comes up regularly.
>>>
>>> James
>>
>> Erlang should not introduce mutable variables because they make it
>> easy to disguise a variety of code smells as clean code.
>>
>> Code like James' example is code that does not express its intentions
>> clearly.
>
> I disagree. Code like this:
> State1 = updateStateSomehow1(State, SomeVariable),
> State2 = updateStateSomehow2(State1, SomeOtherVariable),
> State3 = updateStateSomehow3(State2, SomeReallyOtherVariable),
>
> quite clearly expresses the intention: update the state.

What is the actual intention behind updating the state? I would refuse  
to approve a colleague's code if they argued that its intent was to  
update the state. I think this is another counter-example that  
indicates a lack of code quality rather than a real Erlang problem. It  
is equivalent to saying that the intention of "i++" is to increment "i".

> [...]
>> If you give semantic names to each transformation applied to the  
>> data,
>> then the code will express its intentions clearly. When you express
>> your intentions clearly you avoid a lot of bugs. Subsequent
>> refactoring work is also made easier, especially when the original
>> author is unavailable.
>
> The problem with detailed semantic names is that they tend to be long.
> Given the ugliness of the erlang record syntax you'd soon end up with
> experssions like this:
> StateUpdatedWithSomeVariable#stateRecord.some_field

You can avoid this problem by choosing short semantic names which have  
domain meaning in your client code independent of the transformations.  
The transformations are the implementation of your intentions, they  
are not the intentions themselves.

> instead of the intuitive
> State.some_field
>
> which is actually readable and fits on the terminal nicely, unlike the
> erlang variant.


Despite using semantic naming I have never had any difficulty writing  
Erlang that fits within 80  characters per line (a standard terminal).

At a more fundamental level; if you change the state of a data  
structure, then it makes sense for your process state (ie. the  
function the process is executing and its arguments) to change along  
with it. This is a common idiom in functional programming and is used  
extensively in Erlang's standard library modules.

Going against the grain is what makes it difficult to write code like  
this. It is deliberately difficult to write, because it is  
inconsistent with the functional programming paradigm.

Rather than fighting the abstractions and constraints of the language,  
why not leverage them to improve your productivity and code quality?



More information about the erlang-questions mailing list