Eljay Wrote:

> /*
> 
> Although D 2.0 is a multi-paradigm programming language, it does not support
> two paradigms:
> + reflective programming
> + dynamic typing
> 
> Since D 2.0 does not have support for reflective programming, nor support for
> dynamic typing, I thought "What facilities does D 2.0 have which could be used
> to mimic reflective programming and dynamic typing?"
> 
> (Unless I'm mistaken, and D 2.0 does support these paradigms.  Andrei and 
> Walter
> have been very busy!  In which case... oops.)
> 
> This toy program is the result.
> 
> This toy program does not try to achieve efficient performance.
> 
> Id - root class for all dynamic types.
> Msg - a string:string associative array.
>       TODO. Need to change to string:Id dictionary, but that's for later.
>       TODO. Need to have Id wrapper for string, and other primitives.
> Sel - the selector, which is the "@" key bound to the selector string in the
> string dictionary.
> 
> What is lacking?
> - Should be able to add message responders to an object.
>   What does this mean?
>   Create an object.
>   Insert a message responder.
>   Send that message, and notice that the object now performs that message.
>   Only affect that instantiated object, not the whole class.
> 
> - Should be able to add message responders to a class.
>   What does this mean?
>   If someone has a black box class called MyString, you should be able to 
> inject
>   a brand new message responder into that class which affects ALL instances of
>   MyString.
>   Upshot: you can inject new message handlers to an existing class, which is 
> not
>   a class to which you have the source.
> 
> - Should be able to override message responders to a class, and inject your 
> own
>   message responder.
>   What does this mean?
>   Let's say you want to do some "first grade debugging" on a class, you should
>   be able to programmatically get the message responder of a class (even a 
> class
>   to which you do not have the source),
>   save that message responder, inject your own diagnostic message responder 
> into
>   a class (or into a single instantiated object), output the diagnostics than
>   invoke the original message responder.
> 
> - Classes themsleves should be singleton (or monostate) objects, which are
>   object instantiation factories.
>   Objective-C designates class message responders and object message 
> responders
>   by (note the leading '+' and '-'):
>   + (void)IAmAClassMessageResponder(void)
>   - (void)IAmAnObjectMessageReponder(void)
> 
> Just as a programmer can do object-oriented programming in pure C, even though
> the C programming language provides no language support for object-oriented
> programming, so too can you do reflective programming in D.  Even though D 
> does
> not provide any dynamic typing and reflecting programming support in the D 
> core
> language.
> 
> The only thing that is required to do reflective programming and have dynamic
> typing in D is superhuman discipline, and adhering meticulously to a rigid
> programming convention and never ever make a mistake.
> 
> */
> 
> import std.stdio;
> import std.conv;
> 
> alias string[string] Msg;
> 
> /*
> ** This is the ultimate root of all reflective objects.
> ** Wouldn't it be nice if this were class object?
> */
> class Id
> {
>       void perform(in Msg msg)
>       {
>               switch(msg["@"])
>               {
>                       default:
>                       {
>                               writeln("Unable to perform \"", msg["@"], "\"");
>                       }
>                       break;
>               }
>       }
> };
> 
> /*
> ** This is an example of a useful object which does something interesting.
> */
> class IdFoo : Id
> {
>       void perform(in Msg msg)
>       {
>               switch(msg["@"])
>               {
>                       case "add":
>                       {
>                               performAdd(msg);
>                       }
>                       break;
> 
>                       case "sub":
>                       {
>                               performSub(msg);
>                       }
>                       break;
> 
>                       case "mul":
>                       {
>                               performMul(msg);
>                       }
>                       break;
> 
>                       case "div":
>                       {
>                               performDiv(msg);
>                       }
>                       break;
> 
>                       default:
>                       {
>                               super.perform(msg);
>                       }
>                       break;
>               }
>       }
> 
>       void performAdd(in Msg msg)
>       {
>               double a = toDouble(msg["a"]);
>               double b = toDouble(msg["b"]);
>               writeln(a, " + ", b, " = ", (a + b));
>       }
> 
>       void performSub(in Msg msg)
>       {
>               double a = toDouble(msg["a"]);
>               double b = toDouble(msg["b"]);
>               writeln(a, " - ", b, " = ", (a - b));
>       }
> 
>       void performMul(in Msg msg)
>       {
>               double a = toDouble(msg["a"]);
>               double b = toDouble(msg["b"]);
>               writeln(a, " * ", b, " = ", (a * b));
>       }
> 
>       void performDiv(in Msg msg)
>       {
>               double a = toDouble(msg["a"]);
>               double b = toDouble(msg["b"]);
>               writeln(a, " / ", b, " = ", (a / b));
>       }
> }
> 
> /*
> ** This is an example of a null object.
> ** Imagine that the null object is a noisy debugging object, used to 
> substitute
> ** in for an object which has been destroyed.
> */
> class IdNull : Id
> {
>       void perform(in Msg msg)
>       {
>               switch(msg["@"])
>               {
>                       default:
>                       {
>                               performDiscard(msg);
>                       }
>                       break;
>               }
>       }
> 
>       void performDiscard(in Msg msg)
>       {
>               writeln("Discard ", msg["@"]);
>       }
> }
> 
> /*
> ** This is an example of a proxy object, which forwards message to an object
> ** elsewhere.
> **
> ** Imagine that the other object exists on another computer, and this 
> forwarding
> ** object sends messages to the remote object over an IP/TCP connection.
> */
> class IdForward : Id
> {
>       void perform(in Msg msg)
>       {
>               switch(msg["@"])
>               {
>                       default:
>                       {
>                               performForward(msg);
>                       }
>                       break;
>               }
>       }
> 
>       void performForward(in Msg msg)
>       {
>               writeln("Proxy object forwarding message ", msg["@"]);
>               forwardObj.perform(msg);
>       }
> 
>       this(Id obj)
>       {
>               forwardObj = obj;
>       }
> 
>       Id forwardObj;
> }
> 
> void Exercise(Id obj)
> {
>       Msg msg;
> 
>       // [obj addWithA:5 withB:3]     -- Objective-C
>       // obj(add a:5 b:3)             -- Pseudo-D ... perhaps?
>       // obj(add a:"5" b:"3")            closer to what we are actually doing
>       //                                 but not what's ultimately desired.
>       msg["@"] = "add"; // Just using "add", but could have been 
> "addWithA:withB:"
>       msg["a"] = "5";
>       msg["b"] = "3";
>       obj.perform(msg);
> 
>       // [obj subWithA:5 withB:3]
>       // obj(sub a:5 b:3)
>       msg["@"] = "sub";
>       obj.perform(msg);
> 
>       // [obj mulWithA:5 withB:3]
>       // obj(mul a:5 b:3)
>       msg["@"] = "mul";
>       obj.perform(msg);
> 
>       // [obj divWithA:5 withB:3]
>       // obj(div a:5 b:3)
>       msg["@"] = "div";
>       obj.perform(msg);
> 
>       // [obj fooWithA:5 withB:3]
>       // obj(foo a:5 b:3)
>       msg["@"] = "foo";
>       obj.perform(msg);
> }
> 
> void main()
> {
>       Id obj = new IdFoo;
>       writeln(">>> Exercise IdFoo");
>       Exercise(obj);
> 
>       obj = new IdNull;
>       writeln("\n>>> Exercise IdNull");
>       Exercise(obj);
> 
>       obj = new IdForward(new IdFoo);
>       writeln("\n>>> Exercise IdForward(IdFoo)");
>       Exercise(obj);
> 
>       writeln("---done---");
> }
> 
> 
Could you please give a three or four line example of what it is you want to 
achieve.

Reply via email to