Nice TWiki > Dev > FeatureProposals > DynamicMembers TWiki webs:
Dev | Doc | Main | TWiki | Sandbox
Dev . { Changes | Index | Search | Go }

Dynamic Members

This is the ability for a class to add members to their class at runtime. Actually, that's not what I'm proposing. I really want classes to be able to make it appear that they have other members at runtime. This could be implemented in (at least) two ways.

`.` Operator

One way would be to allow programmers to override the `.` operator. This would be very powerful, especially if the compiler would allow other things besides simple names after the dot, such as ints, floats, or booleans.

Examples

    Object `.`(row@Results, String column) {
        return rs.getObject(column);
    }
    Object `.`(row@Results, int column) {
        return rs.getObject(column);
    }

    Results row = connection.execSql("select fullName, address from Employees");
    String name = (String)row.1;
    String addr = (String)row.address;

If we had unknown implemented (see UnknownType) then this would be even cooler:

    unknown `.`(row@Results, String column) {
        return rs.getObject(column);
    }
    unknown `.`(row@Results, int column) {
        return rs.getObject(column);
    }

    Results row = connection.execSql("select fullName from Employees");
    String name = row.1;        // no type casting needed
    String addr = row.address;

Another advantage to overriding the `.` operator could be to implement dynamic method calls. I haven't explored this idea much, but it could be very powerful.

DynamicMember interface

If allowing an override of the `.` operator proved too difficult (darn), here's another possibility. We could have a special interface, maybe called DynamicMember, or just Dynamic. The compiler could assume that any class that implemented this interface would have a Object getMember(String name) method, or something similar. It would call this instead of it's normal field lookups.

Normal Members

The compiler needs to be intelligent enough, however, to do normal member lookups for the normal (public, protected, and private) members of the class. It would only do dynamic lookups when members are accessed which have not been declared. This means that dynamic members may not be found at runtime. Which necessitates a possibly new Exception class for this situation, which the programmer of the dynamic class would throw.

Reflection

It would be a really cool bonus, I think, if Nice could implement reflection on these dynamic members, so they would appear as if they were full-class citizens with the normal members of the class.

-- TroyHeninger - 25 Oct 2003

One question is whether this is important to use . in these cases. Sure, it looks good. On the other hand, it can hide the fact that the operation can fail. In that case, you could decide to use another operator, say `/`:

    <T> T `/`(row@Results, int column) = cast(row.getObject(column));
    <T> T `/`(row@Results, String column) = cast(row.getObject(column));
then you can use it with row/1 or row/"address".

The nice part about this solution is that the compiler does not need to be modified. With `.`, it should mostly be a parsing issue, but it could reveal somewhat tricky still.

Note that for SQL, one could do something even nicer using tuples:

  <T1,T2> (T1,T2) execSql2(Connection c, String query) ...
...
  (String name, String adresse) = connection.execSql2("select fullName from Employees");

With this, you don't even need to handle the result object. Wait, that requires that the fields are ordered, is it the case? Otherwise, you would need to pass the names of the fields you want inside the result (but then you don't need the 2).

-- DanielBonniot - 25 Oct 2003

I think it's not a good idea to overload `.` and `/` doesn't look pretty. Why not use the [] syntax in this case?

    <T> T get(row@Results, int column) = cast(row.getObject(column));
    <T> T get(row@Results, String column) = cast(row.getObject(column));

Note that these casts are only needed because these java methods aren't retyped yet.

You can use these 'get' methods like:

String name = row[1];
String addr = row["address"];

-- ArjanB - 25 Oct 2003


I agree that overloading the `[]` operator is a workable solution. But I'd still like everyone to explore the concept of adding runtime members and methods. I'd like you to think again about the proposal for a class to override an interface to accomplish this, called DynamicMembers or DynamicMethods. These could be defined as follows:
interface DynamicMembers {
   java.lang.reflect.Field reflect(String member) throws NoSuchFieldException;
   <T> T get(String member) throws NoSuchFieldException;
   <T> void set(String member, T value) throws NoSuchFieldException;
}

interface DynamicMethods {
   java.lang.reflect.Method reflect(String method) throws NoSuchMethodException;
   <T> T call(String method, Object[] args) throws NoSuchMethodException;
}
The Nice compiler would compile code that accesses any undeclared methods or members without a compile error, but only when a class implements these interfaces, respectively. It would produce bytecodes that call the methods of these interfaces. Classes implementing these would be able to easily, dynamically add members or methods at runtime by implementing these interfaces.

Lastly, if no one has time to look into implementing these in the compiler, I'd be happy to take a stab at it myself. But I'd need to be added as a developer to the project. And I'd like to be given at least some pointers to where I should start looking at the necessary changes.

-- TroyHeninger - 11 Nov 2003

Could you give an example of application of these Dynamic interfaces? Above, you first introduced them as an alternative to overloading `.`, in case that is too complicated. But overloading `.` is rather simple, it's just a matter of parsing. The only question about it is wether we really use the `.` symbol (elegant, but possibly confusing) or use another symbol. The Dynamic interfaces look harder to implement, but they are also more powerful, since they are a runtime feature, while `.` is compile time. So examples would help, with comparison with, for instance, Arjan's proposal.

We will certinaly be glad to welcome you in the development team. The tradition is to first let you submit a few patches, and then grant you commit rights. That should not restrict you in the begining.

-- DanielBonniot - 12 Nov 2003

Worthy Examples

I can think of three examples off the top of my head: web programming, database programmin, XML programming, and properties. I'm sure there are many more. Let me illustrate each of these, though I don't have time at the moment to be thurough. I'll add more later...

Web Programming

When your page or servlet receives an HTTP request, instead of getting a simple javax.servlet.Request object, you would get a DynamicMember. All variables passed thru the URL (using GET) or thru a form (POST) would be available as runtime members of thi object. Also, the session object would be a DynamicMember, so that it's members were set at runtime throughout the life of the session. In a language I designed a few years ago, I also had properties attached to web folders/applications, and the servlet's init parameters that both used the DynamicMembers concept. I also had a temp object for each page that was dynamic, that wouldn't get passed in calls to other pages.

Database Programming

Each ResultSet? object should also be a DynamicMember so that each column can easily be accessed or changed as if it's part of the language. I referred to this idea in the introduction above.

XML Programming

XML would be a natural for this. Each Node would be a DynamicMember so that child nodes could be easily accessed, added, changed, or removed at runtime.

I'll add example code, if you need, when I have a little more time. But I hope I've opened your eyes to the possibilities.

-- TroyHeninger - 13 Nov 2003

For XML, you could use the DTD/schema to automatically generate a staticly typed view of the document (this is something very interesting to me, I would love somebody to explore this idea).

Could you, for instance, expand the database example, and explain how your proposal would improve over Arjan's?

-- DanielBonniot - 17 Nov 2003

Topic DynamicMembers . { Edit | Attach | Ref-By | Printable | Diffs | r1.8 | > | r1.7 | > | r1.6 | More }
Revision r1.8 - 17 Nov 2003 - 16:12 GMT - DanielBonniot
Parents: WebHome > FeatureProposals
Copyright © 1999-2003 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback.