www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Interface and delegate D2.0

reply =?ISO-8859-1?Q?Oliver_R=fcbenk=f6nig?= <oliver.ruebenkoenigREM web.de> writes:
Hello Everyone,

the following code segment works. However, I am not sure I understand why it
does work. Also, I have some questions regarding way I did it. 

I'd appreciate all sorts of comments you might have. Thanks.

---------------

import std.stdio;

//alias Expr delegate ( ) aFn; 
alias Expr delegate ( Expr ) aFn;

interface Expr {
    void print();
    aFn analize();
}

Expr eval( Expr e, Expr env ) {
    //return e.analize()();
    return e.analize()( env );
}

class String : Expr {
public:
    this( const char [] stringData )    { this.itsStringData = stringData; }
    void print()                        { writef("\"",
this.itsStringData,"\""); }
    //aFn analize()                     { return { return cast(Expr)this; }; }
    aFn analize()                       { Expr help( Expr env ) {
                                                this.print();
                                                return cast(Expr)env; }
                                            return &help;
                                         }
private:
    const char [] itsStringData;
}

String makeString( const char [] stringData ) {
    return new String( stringData );
}

int main( char[][] arg ) {

    writefln();
    Expr s = makeString("Wow");
    Expr s2 = makeString("!");
    s.print();
    writefln();
    //s.analize()().print();
    s.analize()(s2).print();
    writefln();
    eval( s, s2 ).print();
    writefln();

    return 0;
}


---------------

1) In the String class is it possible to avoid the use of the "help" funcntion?
2) In the String class: why do I need to cast this to Expr - String is derived
from Expr and should fit - should it not?
3) Is it possible to avoid the double brackets in Expr.analize()(Expr)?
Something like Expr.analize(Expr)? I assume this could be done with an alias,
are still the other ways? - well eval is another way. I think i am asking if
you see a way to do the same  thing with less brackets.
4) Of course all other comments are very welcome!

Thanks for your help,
Oliver
Mar 11 2008
parent reply "Neil Vice" <psgdg swiftdsl.com.au> writes:
"Oliver Rübenkönig" <oliver.ruebenkoenigREM web.de> wrote in message 
news:fr5epu$bos$1 digitalmars.com...
 Hello Everyone,

 the following code segment works. However, I am not sure I understand why 
 it does work. Also, I have some questions regarding way I did it.

 I'd appreciate all sorts of comments you might have. Thanks.

 ---------------

 import std.stdio;

 //alias Expr delegate ( ) aFn;
 alias Expr delegate ( Expr ) aFn;

 interface Expr {
    void print();
    aFn analize();
 }

 Expr eval( Expr e, Expr env ) {
    //return e.analize()();
    return e.analize()( env );
 }

 class String : Expr {
 public:
    this( const char [] stringData )    { this.itsStringData = 
 stringData; }
    void print()                        { writef("\"", 
 this.itsStringData,"\""); }
    //aFn analize()                     { return { return 
 cast(Expr)this; }; }
    aFn analize()                       { Expr help( Expr env ) {
                                                this.print();
                                                return cast(Expr)env; }
                                            return &help;
                                         }
 private:
    const char [] itsStringData;
 }

 String makeString( const char [] stringData ) {
    return new String( stringData );
 }

 int main( char[][] arg ) {

    writefln();
    Expr s = makeString("Wow");
    Expr s2 = makeString("!");
    s.print();
    writefln();
    //s.analize()().print();
    s.analize()(s2).print();
    writefln();
    eval( s, s2 ).print();
    writefln();

    return 0;
 }


 ---------------

Firstly a disclaimer: the following comments are based on D2.012.
 1) In the String class is it possible to avoid the use of the "help" 
 funcntion?

You can make use of the following syntax: aFn analize() { return delegate Expr (Expr env) { this.print(); return env; } }
 2) In the String class: why do I need to cast this to Expr - String is 
 derived from Expr and should fit - should it not?

I believe it's because the return type of the inline delegate is determined from your return statement. The syntax to define the return type is in the above example.
 3) Is it possible to avoid the double brackets in Expr.analize()(Expr)? 
 Something like Expr.analize(Expr)? I assume this could be done with an 
 alias, are still the other ways? - well eval is another way. I think i am 
 asking if you see a way to do the same  thing with less brackets.

I have the same gripe myself and haven't found any work around. Neil
Mar 11 2008
parent oliver <oliver.ruebenkoenigREM web.de> writes:
Neil Vice Wrote:

 Firstly a disclaimer: the following comments are based on D2.012.
 
 1) In the String class is it possible to avoid the use of the "help" 
 funcntion?

You can make use of the following syntax: aFn analize() { return delegate Expr (Expr env) { this.print(); return env; } }

that is exactly what i was looking for :-)
 2) In the String class: why do I need to cast this to Expr - String is 
 derived from Expr and should fit - should it not?

I believe it's because the return type of the inline delegate is determined from your return statement. The syntax to define the return type is in the above example.

OK.
 
 3) Is it possible to avoid the double brackets in Expr.analize()(Expr)? 
 Something like Expr.analize(Expr)? I assume this could be done with an 
 alias, are still the other ways? - well eval is another way. I think i am 
 asking if you see a way to do the same  thing with less brackets.

I have the same gripe myself and haven't found any work around.

should you find something I'd be very interested. Thanks for you help. Oliver
Mar 11 2008