<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Generator" CONTENT="MS Exchange Server version 5.5.2653.12">
<TITLE>RE: Structs (was RE: Record selectors)</TITLE>
</HEAD>
<BODY>

<P><FONT SIZE=2>>   With structs you can write things like:</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>>       A = ~{name="joe", footSize=42},   %% define a struct</FONT>
<BR><FONT SIZE=2>>       A.footSize,                       %% access a field</FONT>
<BR><FONT SIZE=2>>       B = ~A{likes="motorbikes"},       %% add a new field</FONT>
<BR><FONT SIZE=2>>       ~{likes=X, name=N} = B}           %% pattern match etc.</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>>   *without* any record defs.</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>>   Everything  is dynamic  (which gives  it a  nice Erlang  flavor) and</FONT>
<BR><FONT SIZE=2>> things are consistent between different modules - so no .hrl files are</FONT>
<BR><FONT SIZE=2>> needed. Efficiency  would be *jolly  good* (TM) if implemented  in the</FONT>
<BR><FONT SIZE=2>> VM.</FONT>
</P>

<P><FONT SIZE=2>We have been thinking about the strengths and weaknesses of structs and how we might have written some of our recent systems using them.</FONT></P>

<P><FONT SIZE=2>A number of our recent systems seem to follow a pattern of:</FONT>
</P>

<P><FONT SIZE=2> - Decode input data into some tagged tuple format (e.g. HTTP Header, Billing Record)</FONT>
<BR><FONT SIZE=2> - Convert this into a record for lots of nice random access and processing.</FONT>
<BR><FONT SIZE=2> - Make a tagged tuple list from the relevant parts of the record.</FONT>
<BR><FONT SIZE=2> - Send this to another process</FONT>
<BR><FONT SIZE=2> - Other process converts it into a record of a new type for random access</FONT>
<BR><FONT SIZE=2> - Other process makes some wierd output packet structure using named record fields.</FONT>
</P>

<P><FONT SIZE=2>I guess this is driven by the need for nice named random access for the processing parts of the application but flexible and extensible tagged tuple lists for communicating between different parts of the app - no need for global .hrl files amd the headaches they bring.</FONT></P>

<P><FONT SIZE=2>For this application structs would appear to be a magic bullet - they are extensible and also random access. Some concerns would be:</FONT></P>

<P><FONT SIZE=2>a) A typo in the name of a single field would be a fairly hard to find bug - unwittingly creating a new field rather than just updating an existing one would be hard to see.</FONT></P>

<P><FONT SIZE=2>b) The absense of default values would make explicit initialisation of many structs mandatory - lots more typing for little gain and potential for more unchecked and hard to find field naming errors.</FONT></P>

<P><FONT SIZE=2>c) It would be very easy to make fairly unreadable code where the same struct name was used many times in the same module to refer to totally different structs.</FONT></P>

<P><FONT SIZE=2>d) We concluded we probably wouldn't use anonymous structs over simple tagged tuples - the possibility for error in field naming and the potential confusion from using the same field names for different instances of a struct (which one is this one again ??) probably outweigh the advantages.</FONT></P>

<P><FONT SIZE=2>One nice benefit would be that it would be very easy to check that input data had the correct number of entries - at the moment validating that the following type of code has filled in all entries in the record needs an extra longwinded trawl through all fields:</FONT></P>

<P><FONT SIZE=2>parse(Vals) -></FONT>
<BR>        <FONT SIZE=2>parse(Vals, #person{}).</FONT>
</P>

<P><FONT SIZE=2>parse([{name, Name}|T], Rec) -></FONT>
<BR>        <FONT SIZE=2>parse(T, Rec#person{name = Name});</FONT>
<BR><FONT SIZE=2>parse([{job, Job}|T], Rec) -></FONT>
<BR>        <FONT SIZE=2>parse(T, Rec#person{job = Job});</FONT>
<BR><FONT SIZE=2>parse([], Rec) -></FONT>
<BR>        <FONT SIZE=2>Rec.</FONT>
</P>

<P><FONT SIZE=2>with structs it would be sufficient to check the number of fields created.</FONT>
</P>

<P><FONT SIZE=2>I think that named structs with the addition of optional static definitions would be an excellent addition to Erlang. (The definitions would have no effect at runtime but would provide a very useful crutch for those of us with weak typing skills.) </FONT></P>

<P><FONT SIZE=2>I would also still like to see xref style support for checking cross module record definitions - and why not global struct definitions as well..</FONT></P>

<P><FONT SIZE=2>Sean</FONT>
</P>
<BR>
<BR>

<P><B><FONT SIZE=2>NOTICE AND DISCLAIMER:</FONT></B>
<BR><B><FONT SIZE=2>This email (including attachments) is confidential.  If you have received this email in error please notify the sender immediately and delete this email from your system without copying or disseminating it or placing any reliance upon its contents.  We cannot accept liability for any breaches of confidence arising through use of email.  Any opinions expressed in this email (including attachments) are those of the author and do not necessarily reflect our opinions.  We will not accept responsibility for any commitments made by our employees outside the scope of our business.  We do not warrant the accuracy or completeness of such information.</FONT></B></P>

</BODY>
</HTML>