[erlang-questions] More general record syntax?
Dowse, Malcolm
malcolm@REDACTED
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:kiszl@REDACTED]
Sent: 23 December 2009 23:40
To: Garrett Smith
Cc: Dowse, Malcolm; erlang-questions@REDACTED
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
<malcolm@REDACTED> 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