Record selectors

Chris Pressey cpressey@REDACTED
Sat Jan 4 12:59:50 CET 2003


On Sat, 4 Jan 2003 03:55:38 +0100
Håkan Stenholm <hakan.stenholm@REDACTED> wrote:

> 
> On fredag, jan 3, 2003, at 12:15 Europe/Stockholm, Chris Pressey wrote:
> 
> > On Thu, 2 Jan 2003 18:50:14 +0100
> > "Daniel Dudley" <daniel.dudley@REDACTED> wrote:
> >
> >> I'm curious as to why it is necessary to specify the record
> >> name when selecting a record instance bound to a variable,
> >> i.e., Variable#RecordName.Field.
> >
> > Because Erlang is a dynamically-typed language.  In a
> > dynamically-typed language, values have types, but variables do not.
> > [...]
> > But consider the case of there being another record definition with a
> > field called 'name', e.g. Country#country.name.  If one were then to 
> > write
> > a function like
> >
> >   print_name(X) -> io:fwrite("~p~n", [X#name]).
> 
> Sure there is if the Virtual machine would keep track of the record 
> definitions (the fieldname - index mapping) and records would be tagged 
> as records rather than being implemented as tuples in the VM.

OK, I guess I should clarify: what I meant was that there's no way that
the *compiler* could tell; the runtime is another matter.

Moreover, it seems clear to me that records in Erlang were designed to
have minimal (essentially zero) impact on performance (they're almost
entirely syntactic.)  This seems very reasonable in light of Erlang being
a language for soft real-time systems.

While the VM could keep a table of which fields belong to which records,
it would mean that

  Person#person.name

instead of compiling to something like

  element(5, Person)

would compile to something like

  element(ets:lookup(field_matrix, {element(1, Person), name}), Person)

Now, my reasoning is, if you're willing to take this sort of performance
hit to access aggregates of data, why restrict yourself to records, when
you could be using dictionaries or "objects" (accessor functions) and get
the benefits associated with those?

In other words, having the VM know which fields go in which records, only
saves you typing (um, keyboard-banging-type typing :), whereas using
dictionaries or objects would also give you extensibility or encapsulation
respectively, for a comparable performance hit.

I'm sure most Erlangers realize that OO techniques are overrated, but on
the other hand, silly is the Erlanger who intentionally avoids an OO
technique when it would actually be useful, simply because "we don't do it
that way."  Encapsulation is, I think, one of those techniques that is
especially germane to this example (e.g. a wrapper function could prevent
Person#person.name from taking on an integer value.)

I guess what I'm saying is that it would probably be more productive to
consider alternative ways of aggregating data, than to try to improve the
existing record system.

A crucial first step, I think, is to allow the programmer to create truly
unique user-defined types - not just using a tuple with the convention
that the first element is the name of the type.  Something like Perl's
"bless" operation comes to mind - a way to create an opaque value with a
type name that may be associated with a module which provides the
operations applicable to values of that type.

This way, a syntax like

  Person#name

could compile to something like

  type_of(Person):name(Person)

or even

  type_of(Person):get_property(Person, name)

This wouldn't interfere with the existing record mechanism (which could be
thought of as "raw" access in comparison to this) while providing the
flexibility, terseness, and abstraction desired by high-level programmers
(without forcing a full-blown OO paradigm on them.)

-Chris



More information about the erlang-questions mailing list