[erlang-questions] Deriving records from one another?

Garrett Smith g@REDACTED
Mon Jun 23 16:08:02 CEST 2014

On Mon, Jun 23, 2014 at 8:49 AM, Roger Lipscombe <roger@REDACTED> wrote:
> I'm probably thinking too OO by calling it "deriving", but here's the problem:
> OTP handlers (gen_server, etc.) take a State parameter. You can stick
> anything in here, but generally I've been using a #state record, and
> keeping a bunch of values in it.
> Now I'd like to actually start representing *state* with the State[1].
> That is, I'd like to be able to match on #init, #ready,
> #expecting_key, #whatever records. This will hopefully make the code
> easier to read, and means that my record doesn't have to contain
> fields for stuff that's not relevant in the given state.
> However, some of the fields *are* shared between states, so my
> question is (in OO terms) how do I derive record types from
> each-other?
> I've thought about using a tuple: {Shared, State} when Shared ::
> #shared{}, State :: #init{} | #etc{}
> That might be hard to read in matches, though, maybe.
> I've thought about using a container record:
> -record(state { shared :: #shared{}, inner :: #init{} | #etc{} }).
> Are there any good solutions[2] to this problem? Or are there better
> ways to do what I'm trying to do?

How many fields are actually shared? Is it really a problem to just
duplicate the values?

I've managed some pretty complex state in the past but it never
occurred to me to use separate records. I would tend to use a single
record field to represent this "lifecycle" state (I think that's what
you're describing) and just load the record up with whatever fields
are needed for all of the various lifecycle states.

If your motivation here is to model your state, as you would in an OO
or other type system, you might just try not doing that and see what
happens. Nested records are very painful and it's hard for me to
envision how this could be paid off in terms of modeling or other
conceptual benefits.

Maps might be your friend -- I'm starting to use them and dealing with
nested maps is 100x better than dealing with nested records.

I have happily dropped the "Is A" thinking and I just go with "how the
heck do I get this to work" -- and then drive the complexity down
until the result is clear to understand (obvious).

Probably not a very clear answer :)

If you provide the various record definitions of what you're thinking,
it might be easier to propose something sane.


More information about the erlang-questions mailing list