rfc: rdbms - new type system

Ulf Wiger (AL/EAB) ulf.wiger@REDACTED
Mon Feb 27 12:35:11 CET 2006


 
ke.han wrote:
>
> I have two basic thoughts on your type syntax:
> 
> 1 - Its too complex/tedious when scanning a large
> list of attributes. It would be nice if the most
> common constraints have higher level shorthand
> notation like I've described.  (If it doesn't 
> effect item 2) you could add these high level
> notations as simple interface on your existing
> syntax.

I've been thinking about a nice syntax for 
parameterized typedefs, but haven't figured it out
yet.


> 2 - I am making wild assumptions about how this is 
> implemented. ;-).  I assume that things like..
> 
>  >> {{attr, age, type},
>  >>   {'and', [{'>=', 0},
>  >>            {'=<', 150}]},
>  >>   {'or', undefined}}
> 
> ..get implemented as a collection of funs or applies.

No, currently, it's just a bunch of pattern matching.
I posted the type checking code in my first message.
My code generator selected type checks that could be 
generated as guards, etc. Currently, I don't do that.
I do have a simplification step, where I try to reduce
the types. It is very naive at the moment.

But Erlang's pattern matching is very efficient. 

> As to the coercedFloat, I did not realize that
> modifying a value on write would slow things down
> much. 

I honestly haven't measured the difference.


> However, if my app code has to check everywhere
> when I retrieve this value, I'm going to slow things
> down anyway.

So, then the question becomes how common this scenario
is. (:


> as to...
> 
>  >>   {{attr, age,
>  >>   	[{integer, {interval, 0, 150},
>  >> 	undefined]}
>  >
>  > Using [T1 .. Tn] as shorthand for
>  > {'or',[T1..Tn]}?
> 
> yes, I think the times you want 'and' operation is when you 
> commit a record and want to cross check different field 
> values. In your notation, for example:
> 
> {{attr, person, record}
> 	{'and', {#person.firstName:length(), '<' ,255}},
> 	{'and', {#person.age, '<', 150}}}

I'm toying with the idea of allowing a match specification
as a table-level 'type' specification:

Ms = [{{1,2,'$1'}, [{is_integer,'$1'}], [{{1,2,{float,'$1'}}}]}].
[{{1,2,'$1'},[{is_integer,'$1'}],[{{1,2,{float,'$1'}}}]}]
10> ets:match_spec_run([{1,2,3}],ets:match_spec_compile(Ms)).

[{1,2,3.00000}]

It sure is ugly, but it's there, and it's fast. It 
is also able to do the type coercion you're asking for.

> 
> I know the above is not correct, but thats the idea...
> 
> so yes, if you are doing a single value check (not checking 
> multiple values in a record) then I implied "or" in a list of 
> constraints is most welcome.
> 
> 	{{attr, age,
> 		[{integer, {inclusive, 0, 100}},
> 		undefined]}
> 
> 
> Also, why the 'type' atom?  isn't it implied we are
> defining types?

No, {type, T} is a reference to a user-defined type.
You can specify your own types either local to a 
table (which means you can refer to it in the type
specifications of any attribute in that table), or
globally, as a 'schema' table property. Any attribute
type can refer to a globally defined type. Locally
defined types shadow the global ones.

> 
> I'm also confused about the difference between type and 
> typedef.  Why not just have a type and types can 
> reuse/inherit other types?  What added value is there to 
> differentiate?

The idea of using the {type, T} wrapper was clarity.
Shorthand notation is nice, but it can also lead to
confusion, and make it easier to make mistakes, I think.

I'd welcome more opinions on this. I want to be able to
find a good balance between strictness, expressiveness 
and simplicity.

/Ulf W




More information about the erlang-questions mailing list