Page 1 of 1
Globally changing field lengths
Posted: Fri Aug 07, 2009 11:11 am
by ConvertFromOldNGs
by JADE News Administrator >> Wed, 28 Oct 1998 23:21:35 GMT
Does anyone out there know if there is a way to define a number of fields in Jade so that they can be changed together ?
For instance, if you had an account number that was 10 characters you might have number of attributes on different objects that are declared as string[10]. The problem is that these are all independantly declared so when the account numbers need to change to 12 digits you are forced to change every one by hand.
Ideally Jade would allow for the definition of "attribute templates" which would define the name, Jade type, size & scaleFactor. Attributes could then be defined via a template and changes to the template would be applied accross the schema.
Anyone got a cunning way to address this issue ?
regards,
Carl
Re: Globally changing field lengths
Posted: Fri Aug 07, 2009 11:11 am
by ConvertFromOldNGs
by JADE News Administrator >> Wed, 28 Oct 1998 23:22:06 GMT
We've seen people address this by creating a class to encapsulate the attribute(s) and then defining references to the class instead of using primitives directly. This isolates the definition, but the property (ie: account number, address, etc) is no longer embedded in the object; it must be created and deleted manually (although deletion can be automatic if you employ parent-child relationships), and it is not automatically fetched from the database with its parent. Often none of this is a problem, but there can be performance issues (wrt using embedded primitives) depending on the volume/level of activity of the parent objects. Another approach I've heard of is to make use of naming conventions (ie: prefixes indicating type) on attributes and then use awk or sed scripts, etc to search/replace in schema files to make global changes. Neither of these is ideal though.
A feature we have had in mind for a while now is the concept of user defined primitives. Developers would be able to define new primitive (ie: embedded) types and then define attributes of these types on their classes. As well as encapsulating the type definition in one place, it would allow the creation of structured attributes (similar to records in other languages) whereby a type could be defined as fields of other types (eg: an address having street name, suburb, city, country and post code). And like primitives, you would have the ability to define methods as well. I think this concept offers a more complete solution, addressing the immediate issue of changing a type definition globally while adding useful new functionality.
Dean.
Re: Globally changing field lengths
Posted: Fri Aug 07, 2009 11:11 am
by ConvertFromOldNGs
by JADE News Administrator >> Wed, 28 Oct 1998 23:22:44 GMT
I really like the idea of having embedded objects. Its offers an elegant mechanism that provides some intresting possibilities.
I've seen some languages that use this idea, where primitives are just objects that are embedded by default. But they can be made seperate via a keyword.
The thing about this technique is that primitives are "proper" objects and are extendable like any other object.
Languages that use this technique and also supported genericity allow things like
Stack[G] ... (definition of a generic stack class)
vars
myIntStack : Stack[Integer]
myCustomerStack : Stack[Customer]
Carl
Re: Globally changing field lengths
Posted: Fri Aug 07, 2009 11:11 am
by ConvertFromOldNGs
by JADE News Administrator >> Wed, 28 Oct 1998 23:23:23 GMT
Why define new primitives
I can't see a reason to define new primitives. Why not just allow subclassing of the existing primitives? This would seem far simpler and more elegant. Most of the behaviour of something like a 10 character string in the original example would be identical to a normal string.
Carl's second posting mentions other languages just treating these as any other object - so they should be! Jade should do the same.
Leigh
Re: Globally changing field lengths
Posted: Fri Aug 07, 2009 11:11 am
by ConvertFromOldNGs
by JADE News Administrator >> Wed, 28 Oct 1998 23:24:13 GMT
I didn't make myself very clear. In discussing user defined primitives, I was talking about two concepts: (i) the ability to subclass existing primitives (which I took for granted), and (ii) the ability to define embedded types (user primitives, composites, records, or embedded objects - as Carl referred to them - which is a good term). Subclassing existing primitives suffices for simple types such as an AccountNumber, where all you probably want to do is constrain the existing String type (eg: define the length, perhaps specify its range, etc) and add some methods. But for more complex types (eg: an Address), this won't do. What's required is the ability to embed instances of Address in their parent, which is what Jade does for primitives so this concept could be extended. Alternatively, we could extend the concept of exclusivity (currently only applicable for collection properties where it's used to define either an exclusive or shared collection) so that when applied to a non-collection reference, the object becomes embedded. Whatever approach is taken, what we've had in mind is the provision of both (i) and (ii).
The decision to distinguish between classes and primitives, and not to treat everything as an object was a deliberate one; trading off OO purism for performance and practicality. Creating primitives as objects to which their parents hold references (eg: a Customer would have *references* to its name, address, phone number, etc) has significant performance implications. Retrieving a Customer instance would effectively return only a set of references; accessing "name" would dereference it which would require another fetch from the database, likewise for "address", "phone number" and so on. This is inefficient. It increases the number of requests to the database, and for every piece of primitive data there is the space overhead of a reference and object header as well. This impacts space (both disk, and memory which in turn impacts cache utilization) and increases network traffic. Optimizations such as automatically fetching referenced objects, and storing primitives by value but with a type indicator can reduce the database requests but still impact space. In the majority of cases, you want properties like "name" and "phone number" to be embedded and behave as primitives with no overhead. In cases where you want the property to behave like an object (eg: for polymorphism), you can implement this yourself by encapsulating the property in a class and referencing an instance of the class. In distinguishing between classes and primitives we made a conscious decision not to penalize the majority of cases.
Dean.
Re: Globally changing field lengths
Posted: Fri Aug 07, 2009 11:11 am
by ConvertFromOldNGs
by JADE News Administrator >> Wed, 28 Oct 1998 23:24:51 GMT
Dean
I liked both concept (I) and (II). This would appear to give the best of both worlds and be more pure OO options. When?
However I don't see the difference between primitives and other classes. I do understand your explanation for treating primitives differently from present classes ( a performance and space problem). Surely primitives can be classes/objects but their behaviour is different. e.g. their "values" only are stored (or embedded)? How Jade deals with their persistence is an implementation issue.
Leigh
Re: Globally changing field lengths
Posted: Fri Aug 07, 2009 11:11 am
by ConvertFromOldNGs
by JADE News Administrator >> Wed, 28 Oct 1998 23:26:00 GMT
For a primitive to behave like an object, it would need to be polymorphic and allow subtypes to extend their supertype by adding attributes (classes do this, so I'm assuming that you'd want primitives to exhibit the same behavior). Both of these *require* storage by reference.
In the discussion that follows, assume that we have a primitive P1 that defines a method m1, and P2 (a subtype of P1) that reimplements m1 and also adds an attribute a1.
Dynamic binding of primitive methods (polymorphism) would require the actual type of the primitive to be known at runtime; a reference knows this, a value doesn't. For example, if we have a property p of type P1 and encounter the line of code:
t := p.m1;
Which implementation of m1 is called? p may store a primitive of type P1 or P2. Unless we know the actual type at runtime, we cannot dynamically bind the call. It would be possible to achieve this without a reference by storing the value and a type header, but this wouldn't address the problem of subtypes extending their supertype by adding attributes.
p is defined as type P1, but we can assign to it primitives of P1 or P2. However, P2 has added an attribute, a1. How much space would we allocate for p in the parent? We could allocate enough to hold the largest subtype, but this risks wasting space and means that we may have to reorg every time we add a new subtype of P1; both unacceptable side effects. To allow such extension, we would store the primitive as a sub-object of the parent with the parent having a reference to the sub-object (which is what is done today for slobs, blobs and exclusive collections). Again, we require a reference.
We've actually been discussing two concepts in these postings: embedded objects, and subtyping primitives.
Embedded objects could be implemented like exclusive collections. They would behave as though they were part of their parent (as a developer you could deal with them as such), but would be implemented as sub-objects; the kernel would automatically take care of creation, deletion and maintaining the sub-object reference. An issue with this is that perhaps the term "embedded object" would become a little misleading as the object wouldn't actually be embedded, it would just appear as though it was. Perhaps "exclusive object" is better.
I don't think we should change the behavior of primitives; we should retain the distinction with classes. To make primitives behave like objects would require storing them by reference, effectively treating them as sub-objects. This is a *requirement* of the implementation; they cannot behave like an object without accepting this cost. And as I mentioned in an earlier posting, we believe there is a strong need for data types whose values are embedded with no additional space or performance overhead.
Dean.
Re: Globally changing field lengths
Posted: Fri Aug 07, 2009 11:11 am
by ConvertFromOldNGs
by
Wilfred Verkley >> Thu, 11 Feb 1999 20:56:35 GMT
Cant "record types" simply be implemented on top of binary primitives? ie the record type simply becomes a "cast" or a map into the binary primitive in which it is actually held and implemented.
Records IMHO dont need to behave like objects ie no dynamic binding or polymorphism, and variables/attributes of a specific record type can only hold values of that type. No intelligent data conversion on re-orgs etc. If you need that, use an object.
I can see two big uses for this kind of feature:
a) Calls to external API's. At the moment we have to manually fill Binary values to simulate records.
b) To create our own simple primitives like Jade's built in Point type.
...-->
Wilfred Verkley
Software Developer
Software Development
Wang NZ Ltd
DDI 9-3087788
Fax 9-3064600
Email
wxv@wang.co.nz