D - [RT] Ramblings of a Mad Man: Let me cast a spell...
- Berin Loritsch (105/105) Dec 04 2003 The talk about casting and templates made me think of a feature that I a...
- Mark Brudnak (42/147) Dec 05 2003 not
- Berin Loritsch (10/38) Dec 08 2003 Not quite. WHat I want is pretty much a dynamic struct with strong typi...
The talk about casting and templates made me think of a feature that I am not sure has been discussed in any language development, but I could definitely use it. It takes the concept of templates even further--removing the need for a large majority of the type of castings that I have to perform. Long and short of it is that I would suggest a strongly typed "properties" type of object. Before I get into the nitty gritty of what it does, let me first explain the need: In the Apache Avalon project, we supply components to client components using a ServiceManager. The ServiceManager provides a way to look up and retrieve a type of component. All the services are bound to a particular name, so any time the client component looks up a particular name, it will be the same type of component. Period. We would love to use generics, but in all known implementations of generics, you can only assign types to all the objects stored. For instance: map<string, void*>; In C++ this would create a map where the key had to be a string, and the returned value could be anything. In Java we are not so lucky, the Map object binds Objects to the lookup value and to the return value. To be fair, the Object type has all that the Map needs to determine the hashcode value and whether two keys are the same. Polymorphism is used to finetune those details. The problem is on the client side where I know what I am looking up, and the type I need: CrisisManager crisis = (CrisisManager) serviceManager.lookup(CrisisManager.ROLE); Even with generics, this is the best I could hope for with the solutions currently available. What I *really* need is to bind a type to the lookup name so that when I retern a value from a lookup service it will always return the same type of object. In fact if I can guarantee this, then I can solve most of my needs for strong typing and losing the cast operator. The solution would be sort of a dynamic struct. Like dynamic arrays (already implemented), the dynamic struct would add new members that have a strong name and stong type bound to it. Call it properties or something, I don't really mind what the final name is: properties foo; // code to assign the properties foo.bar<Baz> = newBaz(); foo.crisisManager<CrisisManager> = getCrisis(); // later on in the client code void doClientThings(properties services) { services.bar.doBazThing(); services.crisisManager.findOpenCrises(); // throws an IllegalAccess exception (it is unassigned) services.unassigned.illegal(); } Any subsequent assignments to a particular type have to be of that type. For example: foo.bar<Bar> = newBar(); // throws an IllegalType exception (it is a Baz type, not a Bar type) foo.bar = newBaz(); And trying to reassign a type is also illegal once it has been set: foo.bar<Bar>; // throws an IllegalOperation exception (it has already been identified) foo.bar<SomethingElse>; And to perfectly round out the entire proposal it would be even more killer to make the dynamic struct readonly after a particular point. For example, if I have the container code set up this dynamic struct, I won't want any of the clients to reassign the objects/components I have painstakenly added to it. Nor would I want them to add new assignments. So if there is a way to freeze the thing, it would totally rock. Perhaps a special purpose property that once the boolean is changed the entire struct becomes hardened like this: properties foo; foo.bar<Baz> = newBaz(); foo.crisisManager<CrisisManager> = getCrisis(); foo.writeable = false; // all of these throw IllegalAccess exception foo.bar = anotherBaz(); foo.subjectManager<SubjectManager = getSubjects(); foo.writable = true; Or perhaps a "method" would be the way to go. Perhaps assigning it as a const is enough. Dunno. However this thing would help out alot. IMPLEMENTATION DETAILS ---------------------- This is only one of the many possible ways to implement this feature. Internally this would be an map<string, struct{Class type; Object value;}> that is hidden by the compiler. (I am thinking easiest to implement from my POV). A lookup would be translated to something like this: struct{Class type; Object value;} entry = map[entryName]; userVariable = (entry.type)entry.value; Something along those lines would be good enough. This is not the only way to implement this thing at all. Perhaps you could come up with new and exciting ways yourself. CAVEAT ------ This does mean that type checking has to be done at runtime instead of compile time. This is an unavoidable side effect. Perhaps some compile time checking [RequiredEntry(example, foo)] [RequiredEntry(example, bar)] void myMethod(properties example) { // no errors example.foo.doSomething(); example.bar.doSomething(); // compile time error example.baz.doSomething(); } Also if those same attributes were available at runtime, it could help the container code (i.e. initializing code) to build the properties object with the expected values. In my experience, any one client would only need a few of these attributes. Of course, it would be cumbersome to have to type all these entries for every method that uses the type. To that end, attribute sets would be even better. But that is another topic altogether.
Dec 04 2003
"Berin Loritsch" <bloritsch d-haven.org> wrote in message news:bqned2$fgn$1 digitaldaemon.com...The talk about casting and templates made me think of a feature that I amnotsure has been discussed in any language development, but I coulddefinitely useit. It takes the concept of templates even further--removing the need foralarge majority of the type of castings that I have to perform. Long and short of it is that I would suggest a strongly typed "properties"typeof object. Before I get into the nitty gritty of what it does, let mefirstexplain the need: In the Apache Avalon project, we supply components to client componentsusinga ServiceManager. The ServiceManager provides a way to look up andretrievea type of component. All the services are bound to a particular name, soanytime the client component looks up a particular name, it will be the sametypeof component. Period. We would love to use generics, but in all known implementations of generics, you can only assign types to all the objects stored. For instance: map<string, void*>; In C++ this would create a map where the key had to be a string, and the returned value could be anything. In Java we are not so lucky, the Map object binds Objects to the lookup value and to the return value. To be fair, the Object type has all that the Map needs to determine the hashcode value and whether two keys are the same. Polymorphism is used to finetune those details. The problem is on the client side where I know what I am looking up, and the type I need: CrisisManager crisis = (CrisisManager) serviceManager.lookup(CrisisManager.ROLE); Even with generics, this is the best I could hope for with the solutions currently available. What I *really* need is to bind a type to the lookup name so that when I retern a value from a lookup service it will always return the same type of object. In fact if I can guarantee this, then I can solve most of my needs for strong typing and losing the cast operator.What I think you are saying is that you would like to look up a type based on a string like this, class myClass = repository.lookup("aClassName") ; object anObject = myClass.new ; If this is what you mean, then you are talking about a metaclass, like Smalltalk? A class is just another object of type "MetaClass".The solution would be sort of a dynamic struct. Like dynamic arrays(alreadyimplemented), the dynamic struct would add new members that have a strongnameand stong type bound to it. Call it properties or something, I don'treallymind what the final name is:You can instantiate a meta class at run time to create a new class. class newClass = new class ; newClass.addInterface("foo") ; newClass.addInterface("bar") ;properties foo; // code to assign the properties foo.bar<Baz> = newBaz(); foo.crisisManager<CrisisManager> = getCrisis(); // later on in the client code void doClientThings(properties services) { services.bar.doBazThing(); services.crisisManager.findOpenCrises(); // throws an IllegalAccess exception (it is unassigned) services.unassigned.illegal(); } Any subsequent assignments to a particular type have to be of that type. For example: foo.bar<Bar> = newBar(); // throws an IllegalType exception (it is a Baz type, not a Bar type) foo.bar = newBaz(); And trying to reassign a type is also illegal once it has been set: foo.bar<Bar>; // throws an IllegalOperation exception (it has already been identified) foo.bar<SomethingElse>; And to perfectly round out the entire proposal it would be even morekiller tomake the dynamic struct readonly after a particular point. For example,ifI have the container code set up this dynamic struct, I won't want any oftheclients to reassign the objects/components I have painstakenly added toit.Nor would I want them to add new assignments. So if there is a way tofreezethe thing, it would totally rock. Perhaps a special purpose property that once the boolean is changed the entire struct becomes hardened like this: properties foo; foo.bar<Baz> = newBaz(); foo.crisisManager<CrisisManager> = getCrisis(); foo.writeable = false;That is the beauty of access functions and properties. This feature does not need to be built into the language.// all of these throw IllegalAccess exception foo.bar = anotherBaz(); foo.subjectManager<SubjectManager = getSubjects(); foo.writable = true; Or perhaps a "method" would be the way to go. Perhaps assigning it as aconstis enough. Dunno. However this thing would help out alot. IMPLEMENTATION DETAILS ---------------------- This is only one of the many possible ways to implement this feature. Internally this would be an map<string, struct{Class type; Object value;}>thatis hidden by the compiler. (I am thinking easiest to implement from myPOV).A lookup would be translated to something like this: struct{Class type; Object value;} entry = map[entryName]; userVariable = (entry.type)entry.value; Something along those lines would be good enough. This is not the onlyway toimplement this thing at all. Perhaps you could come up with new andexcitingways yourself. CAVEAT ------ This does mean that type checking has to be done at runtime instead ofcompiletime. This is an unavoidable side effect. Perhaps some compile timechecking[RequiredEntry(example, foo)] [RequiredEntry(example, bar)] void myMethod(properties example) { // no errors example.foo.doSomething(); example.bar.doSomething(); // compile time error example.baz.doSomething(); } Also if those same attributes were available at runtime, it could help the container code (i.e. initializing code) to build the properties objectwiththe expected values. In my experience, any one client would only need afewof these attributes. Of course, it would be cumbersome to have to typeallthese entries for every method that uses the type. To that end, attributesetswould be even better. But that is another topic altogether.
Dec 05 2003
Mark Brudnak wrote:"Berin Loritsch" <bloritsch d-haven.org> wrote in message news:bqned2$fgn$1 digitaldaemon.com...Not quite. WHat I want is pretty much a dynamic struct with strong typing. Essentially, I want to have one class populate the struct and another class to use it. I am not trying to have the client class worry about instantiation of the new object. All I want to do to use the class is this: Crisis[] crises = myDynStruct.crisisManager.getCrises(); Connection conn = myDynStruct.dataSource.getConnection(); It is already populated by something else. THe important thing here is to get away from having to cast everything or pass it as a weaker type.The talk about casting and templates made me think of a feature that I amnotsure has been discussed in any language development, but I coulddefinitely useit. It takes the concept of templates even further--removing the need for What I *really* need is to bind a type to the lookup name so that when I retern a value from a lookup service it will always return the same type of object. In fact if I can guarantee this, then I can solve most of my needs for strong typing and losing the cast operator.What I think you are saying is that you would like to look up a type based on a string like this, class myClass = repository.lookup("aClassName") ; object anObject = myClass.new ; If this is what you mean, then you are talking about a metaclass, like Smalltalk? A class is just another object of type "MetaClass".
Dec 08 2003