Implementing tables - advice wanted

ke han <>
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\)" <> 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