[erlang-questions] More general record syntax?

Garrett Smith g@REDACTED
Thu Dec 24 01:15:21 CET 2009


(switching to top-post)

I'm leery of changing the record definition syntax, in particular
making it more complicated. If you want to version a record, it's
pretty easy to add you own field.

One other thought...

I typically appreciate badrecord errors when I get them, but these
conversion cases might be helped by a more lax check.

This syntax:

  Foo#~foo_v1.field1

(again, making stuff up) says to use the Foo tuple as if it were a
foo_v1 record. The check might simply be that there are at least as
many tuple values as field defs in foo_v1. Basically it's an unsafe
cast.

This syntax:

  Foo#~foo_v1{field1=bar}

would return Foo as its original record type with the updated field
value. The value tuple location would be identified by the position of
field1 in foo_v1, obviously.

This syntax:

  Foo#~foo_v1#foo

would return Foo converted to the foo record format using Foo as if it
were actually foo_v1.

(As far as my "keep the syntax simple" ideals, I've clearly failed :)

Regarding record conversion:

- Provide a lax record checking syntax that ignores the record type
(first tuple item) and complains only when the tuple value count
(ignoring the first item) is less than the field count in the
specified record type.

- Provide a way to coerce a tuple of an alleged type (regardless of
the actual record type) into another record type. The conversion would
be based on matching field names between the two record definitions.

(Btw, if this has been discussed before, my apologies - this seems
fundamental enough to have been an issue for quite a while. Perhaps
there's already a straight forward solution to record conversion that
doesn't require modifying the language.)

Garrett


On Wed, Dec 23, 2009 at 5:39 PM, Zoltan Lajos Kis <kiszl@REDACTED> wrote:
> 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