[erlang-questions] More general record syntax?

Dowse, Malcolm <>
Tue Jan 5 14:20:25 CET 2010


I guess some sort of versioning could fix the issue with hot-upgrading
state. But code would end up being full of version numbers, unless there
was an extra way of specifying a default version number. And there would
be the (admittedly quite small) overhead of passing these around at
runtime.

If version numbers were added, I think it would make more sense for the
internal representation to be {{record_name, Vsn}, Field1, Field2},
instead of {record_name, Vsn, Field1, Field2}. This would be more
backwards compatible, and prevent ambiguities. Take these two records,
and a function to extract the name:

-record(person, {name, age}).
-record(person, "1.0", {name}).

get_name(#person{name = N}) ->
    N;
get_name(#person("1.0"){name = N}) ->
    N.

IMO, you should never have to guess that, in the case of
get_name({person, "1.0", "am I an age or a name?"}), the ordering of the
pattern match would matter.

Also, this would mean that record_info/2 could accept a tuple as its
second argument, which would be reasonably backwards compatible.

Personally, though, I think my suggestion is neater (assuming it makes
sense, which I think it does). The record_info/2 call would be
completely unchanged, and there would be no run-time overhead. In my
proposal, the compile-time vs. run-time distinction is a bit odd, but
it's already present in the language. In almost every respect Erlang is
a dynamically-typed language, but records are the big exception.

Or maybe it's just that at heart I like static typing, and the idea of
doing as much work as possible at compile time. :)

Malcolm

-----Original Message-----
From: Zoltan Lajos Kis [mailto:] 
Sent: 23 December 2009 23:40
To: Garrett Smith
Cc: Dowse, Malcolm; 
Subject: Re: [erlang-questions] More general record syntax?

I would be lying if I said I understood Malcolm's proposal :)
My only problem with records is that they are not versioned. That could 
simply be solved by adding a version field to records. For example:

definition:   -record(rec, "0.1", {field1 = a, field2 = b}).
referral:   #rec("0.1"){field1 = F}   (if there is only one version of 
the record in the given context, the version could be omitted)
representation:   {rec, "0.1", a, b}

This way code change could look like:

code_change(_OldVsn, #rec("0.1"){a = A, b = B}, _Extra) ->
  {noreply, #rec("0.2"){a = A, b = B, c = 0}}.

and would even work for upgrading from unversioned to versioned records.

Regards,
Zoltan.


Garrett Smith wrote:
> On Wed, Dec 23, 2009 at 11:49 AM, Dowse, Malcolm
<> wrote:
>
> -snip-
>
>   
>> My idea was to allow two different atoms for the two uses. The syntax
>> could be something like this:
>>
>> #compile_time_atom/run_time_atom{field1 = val1, field2 = val2, ...}
>>     
>
> Ugh, and I thought it was painful to read *before* the enhancement ;)
>
>   
>> The main reason I'd find the above change useful is that when
>> hot-upgrading a gen_server, the state record definition can change.
>> Since you can't have two different record definitions (old and new)
with
>> the same name, you have to go mucking around with the internal tuple
>> representation of the record.
>>     
>
> You also run into this when Mnesia - any time you need to modify a
> record definition, you have to go though a painful mucking process. I
> haven't seen a particularly clean way to do this, so I'm curious what
> others think here.
>
> Personally, I'd like a way to convert tuples from one record def to
> another. E.g.
>
>   -record(foo, {field1, field2}).
>   -record(foo_v1, {field1}).
>
>   upgrade(Foo_v1) ->
>       #foo(Foo_v1, foo_v1)
>
> Since this would be a compile time conversion, I've introduced some
> hackish "cast" syntax. Not pretty, but you get the idea -- I want a
> foo record and I provide a tuple that complies with the foo_v1
> definition. The first item in the tuple would be ignored since we're
> interested in mapping field values to tuple locations and don't care
> about the original record type.
>
> This doesn't solve pattern matching, but you can always include a
> version field in your record defs. It has the advantage of providing a
> trivial way to transform record tuples.
>
> Garrett
>
> ________________________________________________________________
> erlang-questions mailing list. See http://www.erlang.org/faq.html
> erlang-questions (at) erlang.org
>
>   



More information about the erlang-questions mailing list