<div dir="auto">Hi Bengt,<div dir="auto"><br></div><div dir="auto">Thank you very much for all of your hints and suggestions. It's clear now. </div><div dir="auto"><br></div><div dir="auto"><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Pada tanggal Sen, 11 Mar 2019 05.20, bengt <<a href="mailto:cean.ebengt@gmail.com">cean.ebengt@gmail.com</a>> menulis:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space">I think your code is about learning erlang. Do that first. OTP is the next step.<br><br>Yes, splitting a gen_server into callback module and interface module is not the OTP way (as described in documentation), so while good for a beginner it can be considered bad style by experienced programmers.<br><br>Sorry, but I have not seen any tutorial about how to avoid thinking the same function/module is always in the same process. It is a very fundamental concept (them not being) in Erlang, so just keep it in mind. One way would be to try and make all your three functions the same function, just have different arguments to the loop. Then you must think about it.<br><br><div><br><blockquote type="cite"><div>On 10 Mar 2019, at 11:11, I Gusti Ngurah Oka Prinarjaya <<a href="mailto:okaprinarjaya@gmail.com" target="_blank" rel="noreferrer">okaprinarjaya@gmail.com</a>> wrote:</div><br class="m_-2910958684381146787Apple-interchange-newline"><div><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr">Hi Bengt,<div><br></div><div>Thank you for your review :)</div><div><br></div><div>I don't quite understand with some of your thought. Then i hope you not mind to give more explanation.</div><div><br></div><div>>> Seasoned Erlang programmers will tell you this is not the OTP way, or a waste of modules</div><div>Did you mean my code here: <a href="https://pastebin.com/ECf3jhZ2" target="_blank" rel="noreferrer">https://pastebin.com/ECf3jhZ2</a> wasn't the OTP way? <br>I learn from here: <a href="https://learnyousomeerlang.com/errors-and-processes" target="_blank" rel="noreferrer">https://learnyousomeerlang.com/errors-and-processes</a> and i do really a beginner at programming with erlang.</div><div><br></div><div>>> So only do this until you have a better understanding.</div><div>What is that? Did you mean <i>doing one module with the interface functions to a gen_server and one module for the gen_server callbacks.?</i></div><div>or what?<br><br></div><div>>> Conflating the function (or even more often, module) and the process is a common mistake in the beginning. When my fellow programmers are experienced, but not used >> to process oriented programming.</div><div> Any tutorials / reference for me to avoid this mistake ?</div><div><br></div><div>Thank you :)</div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div></div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Pada tanggal Min, 10 Mar 2019 pukul 14.49 bengt <<a href="mailto:cean.ebengt@gmail.com" target="_blank" rel="noreferrer">cean.ebengt@gmail.com</a>> menulis:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>Conflating the function (or even more often, module) and the process is a common mistake in the beginning. When my fellow programmers are experienced, but not used to process oriented programming, I have found that it helps to put the code that is run in different process in different modules. Ex: one module with the interface functions to a gen_server and one module for the gen_server callbacks. Seasoned Erlang programmers will tell you this is not the OTP way, or a waste of modules. So only do this until you have a better understanding.<br><br>bengt<br><div><br><blockquote type="cite"><div>On 10 Mar 2019, at 04:57, I Gusti Ngurah Oka Prinarjaya <<a href="mailto:okaprinarjaya@gmail.com" target="_blank" rel="noreferrer">okaprinarjaya@gmail.com</a>> wrote:</div><br class="m_-2910958684381146787gmail-m_4133803218338393271Apple-interchange-newline"><div><div dir="ltr"><div dir="ltr">Hi Bengt,<div><br></div><div>Thank you for the idea, <br><br>I've implement your idea, from performance side, i think using two version of function will have better performance because there's no need to checking using IF statement.</div><div><br></div><div>I worry at first to implement this idea, because i think different version of function will have different PID, hahaha it turns out exactly have same PID. <br>this is my new code <a href="https://pastebin.com/ECf3jhZ2" target="_blank" rel="noreferrer">https://pastebin.com/ECf3jhZ2</a> . Please review if there's any improvement needs. </div><div><br></div><div>Thank you </div><div><br></div><div><br></div><div><br></div><div><br></div><div><br><br></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Pada tanggal Min, 10 Mar 2019 pukul 05.23 bengt <<a href="mailto:cean.ebengt@gmail.com" target="_blank" rel="noreferrer">cean.ebengt@gmail.com</a>> menulis:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>Greetings,<br><br>The error happens the second time any of the three processes call erlang:register/2. They already registered themselves the first time. If you want this structure, but not the error, you have to do the register before starting the loop. Eg, split the functions into two. One that do the register and then calls the second that does the loop.<br><br>bengt<br><div><br><blockquote type="cite"><div>On 9 Mar 2019, at 14:41, I Gusti Ngurah Oka Prinarjaya <<a href="mailto:okaprinarjaya@gmail.com" target="_blank" rel="noreferrer">okaprinarjaya@gmail.com</a>> wrote:</div><br class="m_-2910958684381146787gmail-m_4133803218338393271gmail-m_1841625249326328505Apple-interchange-newline"><div><div dir="ltr"><div dir="ltr">Hi Attila Rajmund Nohl,<div><br></div><div>After i implement your suggestion, i get error when execute any of function call_the_*_p()</div><div>for example:<br><br></div><div><div style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo"><span class="m_-2910958684381146787gmail-m_4133803218338393271gmail-m_1841625249326328505gmail-s1" style="font-variant-ligatures:no-common-ligatures">3> newbie:starter().</span></div><div style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo"><span class="m_-2910958684381146787gmail-m_4133803218338393271gmail-m_1841625249326328505gmail-s1" style="font-variant-ligatures:no-common-ligatures"><0.112.0></span></div><div style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo"><span class="m_-2910958684381146787gmail-m_4133803218338393271gmail-m_1841625249326328505gmail-s1" style="font-variant-ligatures:no-common-ligatures">4> newbie:call_the_second().</span></div><div style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo"><span class="m_-2910958684381146787gmail-m_4133803218338393271gmail-m_1841625249326328505gmail-s1" style="font-variant-ligatures:no-common-ligatures">=ERROR REPORT==== 9-Mar-2019::20:35:15.069388 ===</span></div><div style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo"><span class="m_-2910958684381146787gmail-m_4133803218338393271gmail-m_1841625249326328505gmail-s1" style="font-variant-ligatures:no-common-ligatures">Error in process <0.113.0> with exit value:</span></div><div style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo"><span class="m_-2910958684381146787gmail-m_4133803218338393271gmail-m_1841625249326328505gmail-s1" style="font-variant-ligatures:no-common-ligatures">{badarg,[{erlang,register,[pidsecondp,<0.113.0>],[]},</span></div><div style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo"><span class="m_-2910958684381146787gmail-m_4133803218338393271gmail-m_1841625249326328505gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="m_-2910958684381146787gmail-m_4133803218338393271gmail-m_1841625249326328505gmail-Apple-converted-space"> </span>{newbie,the_second_p,0,</span></div><div style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo"><span class="m_-2910958684381146787gmail-m_4133803218338393271gmail-m_1841625249326328505gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="m_-2910958684381146787gmail-m_4133803218338393271gmail-m_1841625249326328505gmail-Apple-converted-space"> </span>[{file,"/Users/okaprinarjaya/Oprek/Erlang-Oprek/oprek-lagi/src/newbie.erl"},</span></div><div style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo"><span class="m_-2910958684381146787gmail-m_4133803218338393271gmail-m_1841625249326328505gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="m_-2910958684381146787gmail-m_4133803218338393271gmail-m_1841625249326328505gmail-Apple-converted-space"> </span>{line,17}]}]}</span></div><div style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span class="m_-2910958684381146787gmail-m_4133803218338393271gmail-m_1841625249326328505gmail-s1" style="font-variant-ligatures:no-common-ligatures"></span><br></div><div style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo"><span class="m_-2910958684381146787gmail-m_4133803218338393271gmail-m_1841625249326328505gmail-s1" style="font-variant-ligatures:no-common-ligatures">{<0.113.0>,"the_second_p()","Halo second p!"}</span></div></div><div><br></div><div>This is my new modified code <a href="https://pastebin.com/iYCxkkuz" target="_blank" rel="noreferrer">https://pastebin.com/iYCxkkuz</a></div><div><br></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Pada tanggal Jum, 8 Mar 2019 pukul 21.03 Attila Rajmund Nohl <<a href="mailto:attila.r.nohl@gmail.com" target="_blank" rel="noreferrer">attila.r.nohl@gmail.com</a>> menulis:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">I Gusti Ngurah Oka Prinarjaya <<a href="mailto:okaprinarjaya@gmail.com" target="_blank" rel="noreferrer">okaprinarjaya@gmail.com</a>> ezt írta<br>
(időpont: 2019. márc. 8., P, 12:11):<br>
><br>
> Hi Folks,<br>
><br>
> I need your help to review my code. I create and linking 3 process manually without using recursive. And inside p1 and p2 i using IF statement to check to make sure spawning process will only once.<br>
><br>
> I mean, is part code below is a good idea?<br>
><br>
> IsPidExists = whereis(xxx),<br>
> if IsPidExists =:= undefined -><br>
> Pid = spawn_link(?MODULE, the_p, []),<br>
> register(xxx, Pid);<br>
> true -> true<br>
> end,<br>
<br>
Generally this is not a good idea, there's a race condition between<br>
checking that the process is registered (the whereis/1 call) and<br>
registering the new process. A better idea is to start the process and<br>
let the process itself to register. If register fails, it means that<br>
there's already a process registered, so the just started process can<br>
terminate. So your code could look like something like this:<br>
<br>
starter() -><br>
spawn(?MODULE, the_first_p, []).<br>
<br>
the_first_p() -><br>
register(pidfirstp, self()),<br>
spawn_link(?MODULE, the_second_p, []),<br>
...<br>
the_first_p().<br>
<br>
Actually if the register call fails, it throws a badarg and the<br>
process dies automatically, simplifying the code.<br>
</blockquote></div>
_______________________________________________<br>erlang-questions mailing list<br><a href="mailto:erlang-questions@erlang.org" target="_blank" rel="noreferrer">erlang-questions@erlang.org</a><br><a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank" rel="noreferrer">http://erlang.org/mailman/listinfo/erlang-questions</a><br></div></blockquote></div><br></div>_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org" target="_blank" rel="noreferrer">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" rel="noreferrer noreferrer" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
</blockquote></div>
</div></blockquote></div><br></div>_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org" target="_blank" rel="noreferrer">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" rel="noreferrer noreferrer" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
</blockquote></div>
</div></blockquote></div><br></div>_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org" target="_blank" rel="noreferrer">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" rel="noreferrer noreferrer" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
</blockquote></div>