[erlang-questions] Re: Concept of Side-effect
Jayson Vantuyl
kagato@REDACTED
Fri Sep 18 03:47:37 CEST 2009
A small addendum.
Note that calling unsafe functions can create side-effects. Things
like gen_server:call, for example, send messages. So you need to be
careful with library functions.
Thinking a bit, other times that you can modify state:
* Changing the process dictionary (most people don't really do this)
* ETS tables (messages in disguise)
* DETS tables (messages in disguise)
* Network Connections (messages in disguise)
* digraphs (messages in disguise)
On Sep 17, 2009, at 6:35 PM, Jayson Vantuyl wrote:
> I'll do better. Here's an example that actually is necessary.
>
> Assume you have two processes. One updates a record in Mnesia, the
> other receives an acknowledgement that it did it.
>
> Mnesia can replay a transaction in times of extreme contention.
> Here's a buggy version of a function that charges some account.
> Look at the fun() inside. It has the side-effect that it sends a
> message to another process.
>
>> charge_account(Requestor,UserId,Amount) ->
>> {atomic,ok} = mnesia:transaction(
>> fun() ->
>> [ Current ] = mnesia:read(account,UserId),
>> OldAmount = Current#account.amount,
>> New = Current#account{ amount = OldAmount - Amount },
>> ok = mnesia:write(New),
>> Requestor ! {updated,New},
>> ok
>> end
>> ).
>
> This function will potentially send the message to Requestor
> multiple times if the transaction has to be retried.
>
> If you want to do this correctly, you can simply modify the function
> like this:
>
>> charge_account(Requestor,UserId,Amount) ->
>> {atomic,Result} = mnesia:transaction(
>> fun() ->
>> [ Current ] = mnesia:read(account,UserId),
>> OldAmount = Current#account.amount,
>> New = Current#account{ amount = OldAmount - Amount },
>> ok = mnesia:write(New),
>> New
>> end,
>> Requestor ! {updated,Result},
>> ).
>
> The inner fun() has no side-effects and can now be safely retried by
> Mnesia.
>
> This is only one instance where side-effects matter. The important
> thing to remember is that state data in Erlang takes the form of
> recursion, processes and messages. If you don't create recurse with
> a modified value, create a process, or send a message, then no state
> is changed. Even when you recurse, your state only affects a single
> process. This property makes it very easy to create very stable
> programs, because you can contain the places that state can get
> corrupted or lost.
>
> Hopefully this helps.
>
> On Sep 17, 2009, at 6:17 PM, Kaiduan Xie wrote:
>
>> Thanks all for the reply. Can someone provide an example in code? For
>> example, a side-effect free function, and its counterpart function
>> with side-effect.
>>
>> Thanks,
>>
>> kaiduan
>>
>> On Thu, Sep 17, 2009 at 11:07 AM, Gene Tani <gene.tani@REDACTED>
>> wrote:
>>>
>>>
>>> On Sep 16, 3:26 pm, Kaiduan Xie <kaidu...@REDACTED> wrote:
>>>> Hi,
>>>>
>>>> Can someone explain what does side-effect means in Erlang? What is
>>>> side-effect free function, and why we need to write side-effect
>>>> free
>>>> function? A concrete example is preferred.
>>>>
>>>> Thanks,
>>>>
>>>> kaiduan
>>>>
>>>> ________________________________________________________________
>>>> erlang-questions mailing list. Seehttp://www.erlang.org/faq.html
>>>> erlang-questions (at) erlang.org
>>>
>>> http://blog.tornkvist.org/blog.yaws?id=1239107937892262
>>>
>>> http://www.cs.chalmers.se/Cs/Grundutb/Kurser/ppxt/HT2007/general/languages/armstrong-erlang_history.pdf
>>> (PDF page 14)
>>>
>>> and a FP vs. OO debate:
>>>
>>> http://news.ycombinator.com/item?id=493963
>>>
>>> ________________________________________________________________
>>> erlang-questions mailing list. See http://www.erlang.org/faq.html
>>> erlang-questions (at) erlang.org
>>>
>>>
>>
>> ________________________________________________________________
>> erlang-questions mailing list. See http://www.erlang.org/faq.html
>> erlang-questions (at) erlang.org
>>
>
>
>
> --
> Jayson Vantuyl
> kagato@REDACTED
>
>
>
--
Jayson Vantuyl
kagato@REDACTED
More information about the erlang-questions
mailing list