Implementing tables - advice wanted
ke han
ke.han@REDACTED
Wed Jun 14 13:38:09 CEST 2006
Please allow me to express a current problem I'm working on and see
if pattern matching on this new type could use "named tags" to match
in addition to or instead of "position and shape" matching.
I have a complex term which represents the view's relationship to the
controller and models. The goal is to allow an app programmer to
specify this term and have my metadata engine restructure the term
into two or more sets of metadata to be efficiently used by the view
and controller "objects". (In this case, the view means that
metadata gets written out as json and is used by my javascript
code). The trouble is the potential complexity of this original
term. Here is an example below:
1: Metadata = rs:metadata(A, %% need to associate any controller pids
to session in A
2: {controller, PersonController, [
3: {validate, throwFirst}, % or throwAll
4: {attributes, [
5: {message, '<=', string},
6: {{country.list, countries}, '<=', [integer, string]}]},
7: {event, {saveButton, onClick}, [sync, save]}, % can I rely on
dojo.event to keep these in order?
8: {event, {cancelButton, onClick}, cancel},
9: {model, person, [
10: {attributes, [
11: {id, '<=', integer},
12: {firstName, '<=>', string},
13: {lastName, '<=>', string},
14: {birthDate, '<=>', date,
15: [{event, onBlur, validate}]},
16: {{country.selection, country}, '<=>', integer} %
infer type integer from list def
17: ]}
18: ]}
19: ]}),
As hopefully may be obvious, the term describes the following:
a View contains a Controller(Holder, really a reference to a pid on
the server)...this is called controller. It contains the pid which
is the PersonController process. From there we set things like (line
3) for the controller to later know how to handle errors on batch
sync from the view; we see a attributes like message (line 5), a
model (line 9) which implies the PersonController must be able to
respond to some message to retrieve such object. Further, we see
definition for attributes of the model such as id, firstName, etc..
(11-16).
The above structure is a simple one.
Line 11 could also be written as:
{{personId, id}, '<=', integer} which would mean the view's id for
the view's id for the person id is personId, but the internal
attribute name of the person object it maps to is id. Also we could
write:
{{personId, id}, '<=', {integer, 1, 1000}} which would bound the
integer value. The term structure for attribute typing and
constraints could get rather complex. BTW, the '<=' means that the
view will receive the value but that the controller will not accept
changes to it; '<=>' means the value is viewable and changeable;
'=>' would be useful for password fields where the user types in the
value and it gets sent to the controller, but never the other direction.
Line 2 could be written as:
{{controller, personController}, PersonController, [...]) which would
mean that the object in the view which holds the controller pid needs
to have id personController instead of default id of controller.
Event descriptions can be written in long or short format as well;
line 8 could be written as:
{event, {cancelButton, onClick}, {personController, cancel}} This
removes ambiguity of the receiver (personController) of the onClick
event.
ok, I think you can see that these terms can have lots of variations.
The question as it relates to a new dictionary syntax is: Can I
describe this structure using a dictionary syntax that would allow me
to more easily write my metadata interpreter which deconstructs this
original term and creates several sets of metadata to be used by the
collaborating mvc participants.?
In javascript frameworks such as dojo, I have seen associative arrays
used as a clean method of calling functions which may have a large
number of optional parameters.
For example, the javascript:
dojo.io.bind({
url: 'HelloWorldResponseGET.php',
handler: helloCallback,
content: {name: dojo.byId('name').value }
});
The above uses an associative array as the argument to dojo.io.bind
(). This allows the programmer to use the same function bind() with
many different combinations of parameters.
This javascript example has little mapping to what I want to do in
erlang (which is pattern matching internal to the call), but does
show the powers of using an associative array in javascript function
args (just to get the mind working ;-)).
Let me take a try at using Joe's proposed syntax to rewrite part of
me my original term:
2: @controller{id=personController, value=PersonController, [
3: @validate{rule=throwFirst},
4: @attributes{list= [
5: @attribute{id=message, viewId= messageDiv, sync='<=',
type=string},
If I write my structure this way, would I find benefits in pattern
matching against named tags instead of or in addition to position and
shape of the term?
Since I haven't seen examples on how this would be done, I'll
experiment with some ides:
@controller{id=Id, value=Value} = Term ->
@attribute{id=Id, externalId=ExternalId, sync=Sync, type=Type} = Term ->
if Id == undefined -> throw error
ExternalId2 = case ExternalId of
undefined -> Id;
ExternalId -> ExternalId
end,
...
@type{name=Name, ....} = Type %% not sure what to do here as type
could have may different structures depending on its type.
The code above is written with the full possibilities of each dict
type and defaults to undefined for any value which is not defined in
the dict (maybe the dict definition could define default values
similar to records, but with added behavior such as @attribute{id,
{externalId, @id}, {sync, '<='}} which would allow direct and
relative defaults.
I'm probably trying to do too much with this, but my point is that If
I don't get added value in pattern matching, then perhaps having the
dictionary syntax only gives value as a slightly better record format???
thanks for putting up with this long post,
ke han
On Jun 14, 2006, at 10:09 AM, Richard A. O'Keefe wrote:
> "Joe Armstrong \(AL/EAB\)" <joe.armstrong@REDACTED> wrote:
> I've been thinking a bit about tables in Erlang.
>
> Erlang really really really (^100) needs tables.
>
> I have written about this in detail suggesting Erlang-appropriate
> syntax, an adequate set of built in functions, and explaining how
> they can be implemented efficiently.
>
> In a Daghstuhl meeting we has a session on the theme "all you need
> are tables - virtually all dynamically typed languages (except
> Erlang)
> have tables. In Lua they are called tables, in Python
> dictionaries, in
> JavaScript associative arrays - the semantics of all these things are
> slightly different but essentially they are the same.
>
> There is one essential difference: Python, Ruby, Javascript, Perl,
> Icon,
> ... all have MUTABLE tables. Erlang data structures are not mutable.
> This has consequences for implementation.
>
> Keys are strings or integers, conseqative ranges of integers
> (very useful for arrays) are handled in a special manner.
>
> The most appropriate keys for Erlang would seem to be atoms.
>
> I'm wondering about how to implement tables.
>
> Let's choose "@" as the table constructor (just about the only
> character
> left, that's unused.
>
> X = @{name="fred", age=23, footSize = 42}
> Name = X.name,
> ...
> The syntax I proposed uses <{...}> for anonymous psi-terms and
> <name{...}> for named psi-terms, e.g.,
> X = <person{name = fred, age = 23, foot_size = 42}>
>
> Now how could I implement this?
>
> Very very cheaply. Basically, a psi-term is
> a tuple, with a different tag,
> whose first element points to a tuple containing the name (if any)
> and the keys, in a standard order.
>
> There is again quite an important difference between the way Erlang
> would use something like this and the way we'd use hash tables; Erlang
> uses _pattern matching_, so that
>
> <person{age = Age, name = Name}> = X
>
> is a normal thing to do. With keys in standard order, this can be
> done
> in a linear scan. For something like
>
> get(X, name)
>
> a binary search is required, but immutable psi-terms are unlikely to
> grow large enough for binary search (especially if cunningly done) to
> be a performance issue at all.
>
> Psi-terms are a good, perhaps even the ideal, replacement for records.
> The analogy with *mutable* hash tables in other languages, which get
> *used* in completely different ways, is probably misleading.
>
> That's not to say that a mutable hash table data type would be of no
> use. It already exists, courtesy of the process dictionary, and if
> you want a light-weight way to implement these things, building on
> top of the process dictionary rather than ets is probably the way
> to go.
>
More information about the erlang-questions
mailing list