Nice TWiki > Dev > FeatureProposals > DynamicMembers (r1.5) 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.


    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.


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.

Topic DynamicMembers . { Edit | Attach | Ref-By | Printable | Diffs | r1.8 | > | r1.7 | > | r1.6 | More }
Revision r1.5 - 12 Nov 2003 - 04:56 GMT - TroyHeninger
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.