<div dir="ltr">Hi everyone,<div><br></div><div>I would like to propose to remove "tuple dispatches" from Erlang.</div><div><br></div><div>The tuple dispatch is the ability to invoke a function or call erlang:apply/3 on a tuple as first argument:</div><div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div>Eshell V9.0 (abort with ^G)</div></div><div><div>1> Var = dict:new().</div></div><div><div><div>{dict,0,16,16,8,80,48,</div></div></div><div><div><div> {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},</div></div></div><div><div><div> {{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}}</div></div></div><div><div>2> Var:size().</div></div><div><div>0</div></div></blockquote><div><br></div><div>This behaviour is considered by most in the community to be undesired and confusing, as it obfuscates the meaning of the code and adds indirection.</div><div><br></div><div>I have also heard this behaviour made it harder to add some optimizations to the VM. I would love if someone more knowledgeable on the area could confirm or deny this. If true, it is also a strong argument to remove such behaviour.</div><div><br></div><div>Another reason for removing it is that the behaviour can be implemented as needed by adding is_tuple/1 checks to the code or more programmatically by using a parse transforms (see note 1 at the bottom for a limitation though). Therefore those who need the behaviour can include it only when necessary and we don't impose it as a semantics to the whole language (and ecosystem).</div><div><br></div><div>I can think of two strategies for removing the behaviour:</div><div><br></div><div>1. Clean-cut: the code responsible for tuple dispatching will be completely removed from the VM and a parse transform will be made available. The parse transform could be part of Erlang/OTP or a separate repository. This change is backwards incompatible at the BEAM level. Code that relies on tuple dispatch without the parse transform on OTP 19 will not work on OTP 20. However, the parse transform should work with any OTP version, so if the parse transform is used during compilation, the code is guaranteed to work on OTP 19 and earlier as well as on OTP 20 onwards.</div><div><br></div><div>2. New byte codes: if we don't want to break backwards compatibility at the BEAM level, I believe our only option is to introduce new bytecodes and a new apply BIF. Usage of the old BIFs and bytecode could emit warnings while we phase them out. A compiler option or parse transform should still be made available if a developer relying on those features wants their code to run without warnings.</div><div><br></div><div>Please let me know if there are other options available,</div><div><br></div><div>I will be glad to send patches and implement the required parse-transforms if this is accepted by the OTP team.</div><div><br></div><div><div style="font-size:13px"><span style="border-collapse:collapse"><b><br class="gmail-Apple-interchange-newline">José Valim</b></span></div><div style="font-size:13px"><span style="border-collapse:collapse"><div><span style="font-family:verdana,sans-serif;font-size:x-small"><a href="http://www.plataformatec.com.br/" target="_blank" style="color:rgb(42,93,176)">www.plataformatec.com.br</a></span></div><div><span style="font-family:verdana,sans-serif;font-size:x-small">Skype: jv.ptec</span></div><div><span style="font-family:verdana,sans-serif;font-size:x-small">Founder and Director of R&D</span></div></span></div></div><div><br></div><div><div class="gmail_signature"><div dir="ltr"><div><br></div><div>Note 1. A parse-transform would be unable to make the following code work in the same way as today:</div><div><br></div></div></div></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div><div class="gmail_signature"><div dir="ltr"><div>erlang:apply(erlang, apply, [dict:new(), size, []])</div></div></div></div></div></blockquote><div><div><div class="gmail_signature"><div dir="ltr"><div><br></div><div>Although I would consider it highly unlikely to exist so it should not be a point of contention.</div><div><br></div></div></div></div>
</div></div>