Thread overview
Help about Template and class inheritance
Oct 14, 2018
Heromyth
Oct 14, 2018
Basile B.
Oct 15, 2018
Heromyth
October 14, 2018
Here is a sample code

```d
import std.stdio;

class Future(T)
{
	T result;

	this(T r) {
		this.result = r;
	}
}

interface IExecutorService {
	// Future!(T) submit(T)(T result);  // can't be implemented
}

abstract class ExecutorService : IExecutorService {
	 Future!(T) submit(T)(T result) {
		return new Future!(T)(result);
	}
}

class ThreadPoolExecutor : ExecutorService {
	// alias submit = ExecutorService.submit;
	
	// override Future!(T) submit(T)(T result) { // can't override it
	// 	return new Future!(T)(result + 10);
	// }
}

void main()
{
	ThreadPoolExecutor service = new ThreadPoolExecutor();
	ExecutorService serviceBase = service;
	IExecutorService serviceInterface = service;

	Future!(int) f = service.submit!int(12);
	writeln(f.result);
	
	f = serviceBase.submit!int(12);
	writeln(f.result);

	// f = serviceInterface.submit!int(12);
	// writeln(f.result);
}

```

The **submit** can't be defined in D as done in Java. See also (search for exchangeMessageVectorsAsync):

https://www.programcreek.com/java-api-examples/?code=aarmea/noise/noise-master/app/src/main/java/com/alternativeinfrastructures/noise/sync/StreamSync.java

So, is there a better way to do this in D?
Any suggestions are welcome.
Thanks.
October 14, 2018
On Sunday, 14 October 2018 at 13:21:00 UTC, Heromyth wrote:
> Here is a sample code
>
> ```d
> import std.stdio;
>
> class Future(T)
> {
> 	T result;
>
> 	this(T r) {
> 		this.result = r;
> 	}
> }
>
> interface IExecutorService {
> 	// Future!(T) submit(T)(T result);  // can't be implemented
> }
>
> abstract class ExecutorService : IExecutorService {
> 	 Future!(T) submit(T)(T result) {
> 		return new Future!(T)(result);
> 	}
> }
>
> class ThreadPoolExecutor : ExecutorService {
> 	// alias submit = ExecutorService.submit;
> 	
> 	// override Future!(T) submit(T)(T result) { // can't override it
> 	// 	return new Future!(T)(result + 10);
> 	// }
> }
>
> void main()
> {
> 	ThreadPoolExecutor service = new ThreadPoolExecutor();
> 	ExecutorService serviceBase = service;
> 	IExecutorService serviceInterface = service;
>
> 	Future!(int) f = service.submit!int(12);
> 	writeln(f.result);
> 	
> 	f = serviceBase.submit!int(12);
> 	writeln(f.result);
>
> 	// f = serviceInterface.submit!int(12);
> 	// writeln(f.result);
> }
>
> ```
>
> The **submit** can't be defined in D as done in Java. See also (search for exchangeMessageVectorsAsync):
>
> https://www.programcreek.com/java-api-examples/?code=aarmea/noise/noise-master/app/src/main/java/com/alternativeinfrastructures/noise/sync/StreamSync.java
>
> So, is there a better way to do this in D?
> Any suggestions are welcome.
> Thanks.

The basic problem you're faced to here is that D class / interface member functions that are templatized are never virtual. I'm not sure if i understand well the JAVA pattern you try to reproduce but since D interfaces can be templatized you can do something like this, using variadics:

import std.stdio;

class Future(T)
{
	T result;

	this(T r) {
		this.result = r;
	}
}

interface IExecutorService(Ts...) {
	static foreach(T; Ts)
	 	Future!T submit(T result);
}

abstract class ExecutorService(Ts...) : IExecutorService!Ts {
	static foreach(T; Ts)
	 	Future!T submit(T result) {
			return new Future!(T)(result);
		}
}

class ThreadPoolExecutor : ExecutorService!int {
	 override Future!int submit(int result) {
	 	return new Future!int(result + 10);
	 }
}

void main()
{
	ThreadPoolExecutor service = new ThreadPoolExecutor();
	ExecutorService!int serviceBase = service;
	IExecutorService!int serviceInterface = service;

	Future!(int) f = service.submit(12);
	writeln(f.result);

	f = serviceBase.submit(12);
	writeln(f.result);

	f = serviceInterface.submit(12);
	writeln(f.result);
}

so that you can submit and have Future for several types.
October 15, 2018
On Sunday, 14 October 2018 at 15:06:49 UTC, Basile B. wrote:
>
> The basic problem you're faced to here is that D class / interface member functions that are templatized are never virtual. I'm not sure if i understand well the JAVA pattern you try to reproduce but since D interfaces can be templatized you can do something like this, using variadics:
>

That's a good try. I want to have a try with template mixin.

About Java's pattern, see also:
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html


The interface ExecutorService has many implements like AbstractExecutorService, ForkJoinPool, ScheduledThreadPoolExecutor, ThreadPoolExecutor etc.

The sample above is updated:

import std.stdio;

class Future(T)
{
	T result;

	this(T r) {
		this.result = r;
	}
}

interface IExecutorService {
	// Future!(T) submit(T)(T result);  // can't be implemented
}

abstract class ExecutorService : IExecutorService {
	 Future!(T) submit(T)(T result) {
		return new Future!(T)(result);
	}
}

class ThreadPoolExecutor : ExecutorService {
	// alias submit = ExecutorService.submit;
	
	// override Future!(T) submit(T)(T result) { // can't override it
	// 	return new Future!(T)(result + 10);
	// }
}

class ForkJoinPool : ExecutorService {
	// alias submit = ExecutorService.submit;
	
	// override Future!(T) submit(T)(T result) { // can't override it
	// 	return new Future!(T)(result * 10);
	// }
}

void testBase(ExecutorService service) {

	writeln("testBase: ", typeid(service));
	
	Future!(int) f = service.submit!int(12);
	writeln(f.result);
}

void testInterface(IExecutorService service) {

	writeln("testInterface: ", typeid(service));
	writeln("testInterface: ", typeid(cast(Object)service));
	
	// Future!(int) f = service.submit!int(12);
	// writeln(f.result);
}

void main()
{
	ThreadPoolExecutor threadPool = new ThreadPoolExecutor();
	ForkJoinPool forkJoinPool = new ForkJoinPool();

	testBase(threadPool);
	writeln();
	testBase(forkJoinPool);
	writeln("\n");
	testInterface(threadPool);
	writeln();
	testInterface(forkJoinPool);
}