Polymorphic record question

Richard A. O'Keefe <>
Tue Jun 20 03:26:58 CEST 2006

Andrew Lentvorski <> wrote:
	I define some basic packet records.  Every packet has a sequence
	number, and I would like to be able to pull out that sequence
	number regardless of packet type like so:
	-record(u_P2PGen, {sequenceNumber}).
	-record(u_P2PSyn, {sequenceNumber, synData}).
	-record(u_P2PFin, {sequenceNumber, finData}).
This seems like a very strange choice.
Whoever said that a data structure could have only one level?
When a bunch of abstract values have some properties in common
and some properties that are NOT in common, use two levels (or
more in some cases):

    -record(p2p, {sequence_number, variant}).
    -record(p2p_syn, {syn_data}).
    -record(p2p_fin, {fin_data}).

    mk_p2p_syn(SNo, Data) ->
	#p2p{sequence_number=SNo, variant=#p2p_syn{syn_data=Data}}.

    mk_p2p_fin(SNo, Data) ->
	#p2p{sequence_number=SNo, variant=#p2p_fin{fin_data=Data}}.

	test() ->
	     Q0 = queue:new(),
	     Q1 = queue:in(#u_P2PSyn{sequenceNumber=1, synData=foo}, Q0),
	     Q2 = queue:in(#u_P2PFin{sequenceNumber=9, finData=bar}, Q1),
	     io:format("Q2: ~p~n", [Q2]),
	     {{value, P0}, Q3} = queue:out(Q2),
	     io:format("P0: ~p~n", [P0]),
	     io:format("SN: ~p~n", [P0#u_P2PGen.sequenceNumber]).
and write this as

    test() ->
	Q0 = queue:new(),
	Q1 = queue:in(mk_p2p_syn(1, foo), Q0),
	Q2 = queue:in(mk_p2p_fin(9, bar), Q1),
	io:format("Q2: ~p~n", [Q2]),
	{{value, P0=#p2p{sequence_number=SNo}}, Q3} = queue:out(Q2),
	io:format("P0: ~p~n", [P0]),
	io:format("SN: ~p~n", [SNo]).

I'm a little surprised that the "downcasting" hack worked at all,
and I wouldn't expect it to _keep_ working in future releases.

More information about the erlang-questions mailing list