<html><head></head><body><div style="color:#000; background-color:#fff; font-family:Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif;font-size:13px"><div id="yui_3_16_0_ym19_1_1505517459498_1633763"><br id="yui_3_16_0_ym19_1_1505517459498_1633764"></div><div id="yui_3_16_0_ym19_1_1505517459498_1633765">>> Adding temporary variables is also nice because you</div><div id="yui_3_16_0_ym19_1_1505517459498_1633766">>can print them when things go wrong.</div><div id="yui_3_16_0_ym19_1_1505517459498_1633767"><br id="yui_3_16_0_ym19_1_1505517459498_1633768"></div><div id="yui_3_16_0_ym19_1_1505517459498_1633769">> Elixir has IO.inspect which you can use to tap into the middle of a pipe chain to output the intermediate state. (A form of the Kestrel combinator iirc)</div><div id="yui_3_16_0_ym19_1_1505517459498_1633770"><br id="yui_3_16_0_ym19_1_1505517459498_1633771"></div><div id="yui_3_16_0_ym19_1_1505517459498_1633772">This is exactly my biggest problem with elixirs pipe operator and why I do not feel comfortable using it except in</div><div id="yui_3_16_0_ym19_1_1505517459498_1633773">the most safest of cases.  It makes debugging and tracking errors more awkward, and I often found myself breaking</div><div id="yui_3_16_0_ym19_1_1505517459498_1633774">long pipes into temporary variables so I can inspect them. Multiple assignment kind of remedies the need for pipes.</div><div id="yui_3_16_0_ym19_1_1505517459498_1633775"><br id="yui_3_16_0_ym19_1_1505517459498_1633776"></div><div id="yui_3_16_0_ym19_1_1505517459498_1633777">Users = lists:filter(fun/1, Users)</div><div id="yui_3_16_0_ym19_1_1505517459498_1633778">Users = lists:map(fun/1, Users)</div><div id="yui_3_16_0_ym19_1_1505517459498_1633779">Users = lists:sort(fun/1, Users)</div><div id="yui_3_16_0_ym19_1_1505517459498_1633780"><br id="yui_3_16_0_ym19_1_1505517459498_1633781"></div><div id="yui_3_16_0_ym19_1_1505517459498_1633782">> So the |> pipe operator is not really perfect in elixir:</div><div id="yui_3_16_0_ym19_1_1505517459498_1633783"><br id="yui_3_16_0_ym19_1_1505517459498_1633784"></div><div id="yui_3_16_0_ym19_1_1505517459498_1633785">> - it is strict with regards to position of the arguments</div><div id="yui_3_16_0_ym19_1_1505517459498_1633786">> - it obscures the original number of arguments to a function (hello </div><div id="yui_3_16_0_ym19_1_1505517459498_1633787">>   tracing)</div><div id="yui_3_16_0_ym19_1_1505517459498_1633788">> - it may compose or nest funny in some cases or other constructs</div><div id="yui_3_16_0_ym19_1_1505517459498_1633789">> - it is limited in what it can do (see my previous post in this thread)</div><div id="yui_3_16_0_ym19_1_1505517459498_1633790">> - it brings the language down a tricky avenue since other similar </div><div id="yui_3_16_0_ym19_1_1505517459498_1633791">>   control flow constructs would need to add more special operators with </div><div id="yui_3_16_0_ym19_1_1505517459498_1633792">>   new semantics</div><div id="yui_3_16_0_ym19_1_1505517459498_1633793">> - other language features may be equivalent to it already</div><div id="yui_3_16_0_ym19_1_1505517459498_1633794"><br id="yui_3_16_0_ym19_1_1505517459498_1633795"></div><div id="yui_3_16_0_ym19_1_1505517459498_1633796">Agree with most of this and want to add you can use anon functions</div><div id="yui_3_16_0_ym19_1_1505517459498_1633797">to remove the strictness of position of args</div><div id="yui_3_16_0_ym19_1_1505517459498_1633798"><br id="yui_3_16_0_ym19_1_1505517459498_1633799"></div><div id="yui_3_16_0_ym19_1_1505517459498_1633800">"5" = </div><div id="yui_3_16_0_ym19_1_1505517459498_1633801">%{key: 5} </div><div id="yui_3_16_0_ym19_1_1505517459498_1633802">  |> (&(:maps.get(:key, &1))).() </div><div id="yui_3_16_0_ym19_1_1505517459498_1633803">  |> Integer.to_string</div><div id="yui_3_16_0_ym19_1_1505517459498_1633804"><br id="yui_3_16_0_ym19_1_1505517459498_1633805"></div><div id="yui_3_16_0_ym19_1_1505517459498_1633806">Piping to &:maps.get(:key, &1) does not work and gives a deprecation warnings</div><div id="yui_3_16_0_ym19_1_1505517459498_1633807">so it leaves me to wonder if it worked before, as its much simpler to read.</div><div id="yui_3_16_0_ym19_1_1505517459498_1633808"><br id="yui_3_16_0_ym19_1_1505517459498_1633809"></div><div id="yui_3_16_0_ym19_1_1505517459498_1633810">Going back to</div><div id="yui_3_16_0_ym19_1_1505517459498_1633811"><br id="yui_3_16_0_ym19_1_1505517459498_1633812"></div><div id="yui_3_16_0_ym19_1_1505517459498_1633813">{ok, Bin} | {error, Reason} = File:read("my_file")</div><div id="yui_3_16_0_ym19_1_1505517459498_1633814"> VS</div><div id="yui_3_16_0_ym19_1_1505517459498_1633815">Bin | throw/1 = File:read!("my_file")</div><div id="yui_3_16_0_ym19_1_1505517459498_1633816"><br id="yui_3_16_0_ym19_1_1505517459498_1633817"></div><div id="yui_3_16_0_ym19_1_1505517459498_1633818">After a good nights sleep I think I will side with this behavior:</div><div id="yui_3_16_0_ym19_1_1505517459498_1633819"><br id="yui_3_16_0_ym19_1_1505517459498_1633820"></div><div id="yui_3_16_0_ym19_1_1505517459498_1633821">If we were to write:</div><div id="yui_3_16_0_ym19_1_1505517459498_1633822"><br id="yui_3_16_0_ym19_1_1505517459498_1633823"></div><div id="yui_3_16_0_ym19_1_1505517459498_1633824">{ok, Bin} = File:read("my_file") </div><div id="yui_3_16_0_ym19_1_1505517459498_1633825"><br id="yui_3_16_0_ym19_1_1505517459498_1633826"></div><div id="yui_3_16_0_ym19_1_1505517459498_1633827">we should instead write: </div><div id="yui_3_16_0_ym19_1_1505517459498_1633828"><br id="yui_3_16_0_ym19_1_1505517459498_1633829"></div><div id="yui_3_16_0_ym19_1_1505517459498_1633830">Bin = File:read!("my_file") </div><div id="yui_3_16_0_ym19_1_1505517459498_1633831"> OR </div><div id="yui_3_16_0_ym19_1_1505517459498_1633832">Bin = MUST File.read("my_file") </div><div id="yui_3_16_0_ym19_1_1505517459498_1633833"> OR..</div><div id="yui_3_16_0_ym19_1_1505517459498_1633834">you get the idea.</div><div id="yui_3_16_0_ym19_1_1505517459498_1633835"><br id="yui_3_16_0_ym19_1_1505517459498_1633836"></div><div id="yui_3_16_0_ym19_1_1505517459498_1633837"><br id="yui_3_16_0_ym19_1_1505517459498_1633838"></div><div id="yui_3_16_0_ym19_1_1505517459498_1633839">Because if File:read/1 returns an error we crash anyways due to our pattern match, and</div><div id="yui_3_16_0_ym19_1_1505517459498_1633840">the only element in position 1 would be 'ok'.</div><div id="yui_3_16_0_ym19_1_1505517459498_1633841"><br id="yui_3_16_0_ym19_1_1505517459498_1633842"></div><div id="yui_3_16_0_ym19_1_1505517459498_1633843">If we were to write case File:read("myfile") do, we should get the {ok, Bin}.</div><div id="yui_3_16_0_ym19_1_1505517459498_1633844"><br id="yui_3_16_0_ym19_1_1505517459498_1633845"></div><div id="yui_3_16_0_ym19_1_1505517459498_1633846">Now the 3rd case is where we store a local variable to case on, </div><div id="yui_3_16_0_ym19_1_1505517459498_1633847"><br id="yui_3_16_0_ym19_1_1505517459498_1633848"></div><div id="yui_3_16_0_ym19_1_1505517459498_1633849">Res = File:read("my_file")</div><div id="yui_3_16_0_ym19_1_1505517459498_1633850">case Res of</div><div id="yui_3_16_0_ym19_1_1505517459498_1633851">  ..</div><div id="yui_3_16_0_ym19_1_1505517459498_1633852">end</div><div id="yui_3_16_0_ym19_1_1505517459498_1633853"><br id="yui_3_16_0_ym19_1_1505517459498_1633854"></div><div id="yui_3_16_0_ym19_1_1505517459498_1633855">To support all 3+ cases we need full control.  For example sometimes I dont like that</div><div id="yui_3_16_0_ym19_1_1505517459498_1633856">:global.register_name crashes instead of returning me a error tuple. Other times I welcome</div><div></div><div dir="ltr" id="yui_3_16_0_ym19_1_1505517459498_1633857">the crash.</div> <div class="qtdSeparateBR"><br><br></div><div class="yahoo_quoted" style="display: block;"> <div style="font-family: Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif; font-size: 13px;"> <div style="font-family: HelveticaNeue, Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif; font-size: 16px;"> <div dir="ltr"><font size="2" face="Arial"> On Thursday, September 28, 2017 11:59 AM, zxq9 <zxq9@zxq9.com> wrote:<br></font></div>  <br><br> <div class="y_msg_container"><div dir="ltr">On 2017年09月28日 木曜日 11:33:29 Fred Hebert wrote:<br clear="none">> I am able to get along fine without it, but if working without a similar <br clear="none">> construct requires 40 posts in a mailing list to make sure other people <br clear="none">> get a solution or pattern they are comfortable with when the operator is <br clear="none">> *not* available, then maybe there's a need to look at ways to improve <br clear="none">> the current state of things.<br clear="none"><br clear="none">I get your point, but this is a fantastic mischaracterization of what is<br clear="none">happening.<br clear="none"><br clear="none">So what IS actually happening?<br clear="none"><br clear="none">We have an explosion of fad languages that keep adding sexy syntax all<br clear="none">over the place. People get sort of used to a few of them and then get<br clear="none">surprised when something new (like matching) is central to this new one<br clear="none">they're not used to, but feel like things are somehow wrong if one they<br clear="none">were expecting (like a composition operator, or objects, or whatever) is<br clear="none">missing.<br clear="none"><br clear="none">What is happening in that fantabulous language space?<br clear="none"><br clear="none">The languages are dying out, suffocating under their own weight and<br clear="none">semantic confusion -- leading to the sudden emergence of new sexy<br clear="none">languages.<br clear="none"><br clear="none">This is actually AWESOME, overall, for the future of programming.<br clear="none">Eventually we are definitely going to figure out on something that is<br clear="none">just flat out Right for a wide variety of general cases.<br clear="none"><br clear="none">But it is actually REALLY BAD for maintenance, writing production code,<br clear="none">onboarding new people who need to be productive, and the stability of<br clear="none">languages overall. Languages don't really evolve -- they become new,<br clear="none">subtly incompatible languages.<br clear="none"><br clear="none">Erlang's focus is production, not research. It cannot afford to be a<br clear="none">fad language. So yes, arguing AGAINST changing it should be a stringent,<br clear="none">even a knee-jerk reaction to any new suggestions. Erlang works quite well<br clear="none">in a shocking variety of domains. Anything new threatens that. New<br clear="none">suggestions absolutely should have to stand up to withering criticism<br clear="none">over and over until their underlying merit finally wins out.<br clear="none"><br clear="none">Python is in the same boat. "40 posts in a mailing list"... have you<br clear="none">seen the extreme reluctance Guido takes to adding new features? There is<br clear="none">a reason. And Python is better for it, still remains consistent, and<br clear="none">has weathered the language storms to the point that it is emerging as<br clear="none">the new Java.<br clear="none"><br clear="none">That didn't happen by adding stuff because it was hip at the moment,<br clear="none">considered cool in some other language, or whatever. He was serious about<br clear="none">the idea that "there should be one, preferrably obvious, way to do it".<br clear="none">Over time it really looks like this has been the more powerful philosophy.<br clear="none"><br clear="none">This thread wasn't even about adding a new feature or keeping one out.<br clear="none">It was about a coding convention Joe ran by us all that sparked a<br clear="none">conversation which attracted the predictable Elixir straphanger who needed<br clear="none">to mention that Elixir has pipe syntax and `with` that can do stuff. Neato.<br clear="none">That's great for Elixir, but a bad fit for Erlang if the only reason is<br clear="none">to add a "me, too" feature.<br clear="none"><br clear="none">I'm not against language advancement, but I am against flippant language<br clear="none">changes. I will play Devil's Advocate for a year, even against features<br clear="none">I think would personally benefit ME, simply because language changes VERY<br clear="none">OFTEN have unintended consequences later that are just super hard to<br clear="none">square after the fact (well, impossible, really). Language design and<br clear="none">syntax are super tricky subjects once you get outside pure lambda calculus.<br clear="none">Let's let the exploration bonanza continue -- elsewhere.<br clear="none"><br clear="none">When it is time to introduce some of these slick features it will be time<br clear="none">for an Erlang 2 (well, called something else hopefully). I do not believe<br clear="none">that language is Elixir, though. It has shown us a lot, but its beginning<br clear="none">to remind me of why Ruby eventually fell apart.<br clear="none"><br clear="none">-Craig<div class="yqt6524803513" id="yqtfd49424"><br clear="none">_______________________________________________<br clear="none">erlang-questions mailing list<br clear="none"><a shape="rect" ymailto="mailto:erlang-questions@erlang.org" href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br clear="none"><a shape="rect" href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br clear="none"></div></div><br><br></div>  </div> </div>  </div></div></body></html>