[erlang-questions] If you are homesick for object.selector

ok <>
Sat Jan 26 11:15:07 CET 2013


I wrote:


> So I don't _want_ to write AXP.a.x.p because that code
> frightens me with its fragility.  The only x.a.b or
> x->a->b I could find in a quick find+grep over my own
> C code on this laptop were two lines in some code to
> handle doubly linked lists.

Imagine me with egg all over my face.
Somehow that find+grep missed an entire directory,
containing a project with lots of code by me and
nobody else, containing hundreds of examples of
what I said I didn't do.

Some of the code is actually benign.  It's not *really*
spanning multiple records.  I have a lot of tagged unions,
   struct Thingy {
      enum Thingy_Tag tag;
      union {
         int i;
         Unique_String s;
         ...
      } u;
   }
and occurrences of thingy->u.s really count as a single
field reference.

However, there were also about 300 lines containing
foo->bar->ugh and I have spent a couple of hours
fixing as many of them as I could.

In many cases, the code was (to my mind) simplified
and clarified by introducing
    gvar const o = m->owner;
    ... o->whatever ...
instead of m->owner->whatever, because it turned out
that o was actually used several times in a function
containing such a double step.  Simply, if I was using
foo->bar->ugh I was almost always _also_ using
foo->bar->zoo and/or plain foo->bar itself.  Before C
compilers got good at optimising, this change would
also have made the object code smaller and faster;
even these days, C's aliasing rules probably mean there's
some benefit there.

I've spotted this in other people's Erlang code too.
Function bodies that contain lots of field references
can often be shortened (and to my mind simplified) by
replacing field references by pattern matching in the
head.

Of the rest, quite a few would have benefited from
virtual fields, had C supported them.  Some of the
ones that are left would have been simpler and easier
for the compiler to type-check had I *not* been using
C format strings.  (The whole program basically doubled
in speed when I stopped using <stdio.h> for most I/O;
the only stdio code left is for error messages.)

But to me the most interesting thing was recalling,
as I worked over the code, that these had been the
most error prone parts of the program.  foo->bar->ugh
really _had_ been a warning sign that I had not
understood years ago when writing this stuff.

Not only that:  the foo->bar->ugh antipattern turned up
a lot in code that needs a rewrite in order to hold
Unicode in certain internal data structures, and I'd
been putting that off and putting it off because fixing
this stuff was so scary.  I hadn't understood _why_ it
was scary, but now I think I do.

Why has it taken me so long to learn not to be so stupid?





More information about the erlang-questions mailing list