Structs (was RE: Record selectors)

Ulf Wiger <>
Wed Feb 12 10:12:27 CET 2003


On Tue, 11 Feb 2003, Chris Pressey wrote:

>To me, OO just means code and data (state) are grouped in
>units.  All the other tenets I've seen seem to follow from
>that principle.  Erlang modules currently work fairly well
>for the purpose, and with enough effort I'm sure any OO
>technique could be implemented on top of them; but more
>usually, I'll bet Erlang programmers just code up discrete
>abstractions to serve the specific purposes they have in
>mind right then.

I fully agree.


>In other words, I find it's really not that different
>programming in Erlang than programming in your typical OO
>language, but you build what you need and only what you
>need of the OO framework when you need it.

Agreed, except a difference is perhaps that the typical
erlang programmer doesn't apply OO models everywhere, but
rather when it makes sense.


>Modules I write
>tend to look a lot like:
>
>  -module(rectangle).
>
>  -record(rectangle, {width, length}).
>
>  new(Config) -> config(#rectangle{}, Config).
>
>  config(Rectangle, []) ->
>    Rectangle;
>  config(Rectangle, [H | T]) ->
>    config(config(Rectangle, H), T);
>  config(Rectangle, {width, N}) when number(N) ->
>    Rectangle#rectangle{ width = N };
>  config(Rectangle, {length, N}) when number(N) ->
>    Rectangle#rectangle{ length = N }.
>
>  width(Rectangle) ->
>    Rectangle#rectangle.width.
>  length(Rectangle) ->
>    Rectangle#rectangle.length.
>
>  perimeter(Rectangle) ->
>    2 * (Rectangle#rectangle.width + Rectangle#rectangle.length).
>
>  etc.

This is a perfectly good way of writing code and, I
believe, a quite common pattern.

>Am I a freak, or do other people find that it helps to
>write modules this way - basically, to hide each data
>structure behind interface code? Would structs obsolete
>this discipline, and if not, how could they be enriched to
>do so?

I think structs can simplify this type of programming. The
main difference between structs and records in this recard
is that with records, you have to have explicit access
functions for each type of record. Thus, if you wanted to
reuse the pattern above for another geometric shape that
also has width and length, and something else (...ehhm, say
a gable roof -- width, length, rise,
http://www.themetalman.net/roofshape.htm), you could reuse
some of the code above, probably skipping perimeter/1, but
you'd still have to change most of the code since it
specifically refers only to a _rectangle_'s width or height,
not just the width or height of any shape. This makes it
more difficult to write generic support functions when
records are involved.

Structs would make this easier, because you can e.g.
stipulate that a given struct should have certain attributes
for a certain function to work. You could even, if you relax
the performance requirement a tiny bit, inspect the struct
to find out if Area should be calculated based on
{width,height}, {width,height,rise}, or radius. OK, a fairly
contrived example, but you get the picture.

You could still use named structs and program _exactly_ as
you have done with records. Then, structs will still give
you better protection against compile-time dependencies, and
will provide added flexibility where it is really needed.

/Uffe
-- 
Ulf Wiger, Senior Specialist,
   / / /   Architecture & Design of Carrier-Class Software
  / / /    Strategic Product & System Management
 / / /     Ericsson AB, Connectivity and Control Nodes




More information about the erlang-questions mailing list