www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Mimicking Java's Type Erasure

reply Superstar64 <Hexagonalstar64 gmail.com> writes:
Consider the following Java code.
--
import java.util.function.Function;
public class Main{

     //basic Rank2 type
     static interface Stringer{
         <A> String show(Function<A,String> type, A that);
     }

     static class Say implements Stringer {
         public <A> String show(Function<A,String> type, A that){
             return type.apply(that);
         }
     }

     static class Shout implements Stringer {
         public <A> String show(Function<A,String> type, A that){
             return type.apply(that) + "!!!";
         }
     }

}
--
This uses Java's generics' type erasure to create a basic rank 2 
type.
What are some clean ways to implement something similar in D, in 
a type safe manner if preferable?
Nov 03 2019
parent reply Heromyth <bitworld qq.com> writes:
On Monday, 4 November 2019 at 00:16:53 UTC, Superstar64 wrote:
 Consider the following Java code.
 --
 import java.util.function.Function;
 public class Main{

     //basic Rank2 type
     static interface Stringer{
         <A> String show(Function<A,String> type, A that);
     }

     static class Say implements Stringer {
         public <A> String show(Function<A,String> type, A that){
             return type.apply(that);
         }
     }

     static class Shout implements Stringer {
         public <A> String show(Function<A,String> type, A that){
             return type.apply(that) + "!!!";
         }
     }

 }
 --
 This uses Java's generics' type erasure to create a basic rank 
 2 type.
 What are some clean ways to implement something similar in D, 
 in a type safe manner if preferable?
String show(A)(Stringer stringer, Function<A,String> type, A that) { Shout shout = cast(Shout)stringer; if(shout !is null) { shout.show(type, that); return; } Say say = cast(Say)stringer; if(say !is null) { say.show(type, that); return; } assert(false, "Unsupported"); } Stringer stringer = new Shout(); stringer.show(type, that);
Nov 03 2019
parent Superstar64 <Hexagonalstar64 gmail.com> writes:
On Monday, 4 November 2019 at 01:25:36 UTC, Heromyth wrote:
 On Monday, 4 November 2019 at 00:16:53 UTC, Superstar64 wrote:
 Consider the following Java code.
 --
 import java.util.function.Function;
 public class Main{

     //basic Rank2 type
     static interface Stringer{
         <A> String show(Function<A,String> type, A that);
     }

     static class Say implements Stringer {
         public <A> String show(Function<A,String> type, A 
 that){
             return type.apply(that);
         }
     }

     static class Shout implements Stringer {
         public <A> String show(Function<A,String> type, A 
 that){
             return type.apply(that) + "!!!";
         }
     }

 }
 --
 This uses Java's generics' type erasure to create a basic rank 
 2 type.
 What are some clean ways to implement something similar in D, 
 in a type safe manner if preferable?
String show(A)(Stringer stringer, Function<A,String> type, A that) { Shout shout = cast(Shout)stringer; if(shout !is null) { shout.show(type, that); return; } Say say = cast(Say)stringer; if(say !is null) { say.show(type, that); return; } assert(false, "Unsupported"); } Stringer stringer = new Shout(); stringer.show(type, that);
I don't think you understood my question. Your `shout.show(type,that)` expression wouldn't compile because you can't have you can't have a templated virtual function in an interface(a rank 2 type). What I'm asking if there is a way to take a rank 1 type and create a delegate to it. `` string show(A)(string delegate(A) callback, A that){ // ... } void main(){ // borrow haskell's syntax for a minute (forall A. string delegate(string delegate(A),A)) shower = show; show(a => a,"hello").writeln; } `` Now I understand this isn't possible natively possible because of how D's templates works, but I'm asking if there's a good workaround to replicate that behavior.
Nov 03 2019