Re: ... use of ... is hidden by ...; use alias ... to introduce base class overload set ??

2019-10-26 Thread Robert M. Münch via Digitalmars-d-learn

On 2019-10-25 15:20:21 +, Ali ‡ehreli said:


On 10/25/2019 07:34 AM, Robert M. Münch wrote:

 > If the compiler is a 1-pass one I see the problem, otherwise one could
 > first get a "total overview" and create the necessary vtbl entries after
 > everything is known. Maybe this is not "how a compiler is implemented"
 > but the problem sounds solvable for me.

Unfortunately, it's not the compiler but the linker that produces the 
program (dmd and others conveniently call the linker behind the scenes).


Yes, sure...

It's common to compile the compilation units e.g. with "dmd -c" and 
then link them together at the end. C++ has been suffering from the 
fact that linkers are language agnostic but the linker is a part of the 
operating system, so this is what we got.


Otherwise, I would agree with you. But even then, what about dynamic 
libraries? The library was built with 7 instances of a template but I 
have 8 instances in my program. This is related to the operating system 
'loader', which happens to be the sister of the 'linker'. :)


The thing here would be to "instrument" or generate other code if such 
a case shows up, so be prepared for the case when such a dynamic case 
shows up. However, I can imagine that at the end one ends with a VM, 
that provides an eco-system that abstracts all these problems away... 
but than you are no longer a system language and won't have the common 
C compatible ABI.


I'll live the with cicumstance and as you showed, there is a solution 
to the problem.


--
Robert M. Münch
http://www.saphirion.com
smarter | better | faster



Re: ... use of ... is hidden by ...; use alias ... to introduce base class overload set ??

2019-10-25 Thread Ali Çehreli via Digitalmars-d-learn

On 10/25/2019 07:34 AM, Robert M. Münch wrote:

> If the compiler is a 1-pass one I see the problem, otherwise one could
> first get a "total overview" and create the necessary vtbl entries after
> everything is known. Maybe this is not "how a compiler is implemented"
> but the problem sounds solvable for me.

Unfortunately, it's not the compiler but the linker that produces the 
program (dmd and others conveniently call the linker behind the scenes).


It's common to compile the compilation units e.g. with "dmd -c" and then 
link them together at the end. C++ has been suffering from the fact that 
linkers are language agnostic but the linker is a part of the operating 
system, so this is what we got.


Otherwise, I would agree with you. But even then, what about dynamic 
libraries? The library was built with 7 instances of a template but I 
have 8 instances in my program. This is related to the operating system 
'loader', which happens to be the sister of the 'linker'. :)


Ali




Re: ... use of ... is hidden by ...; use alias ... to introduce base class overload set ??

2019-10-25 Thread Robert M. Münch via Digitalmars-d-learn

On 2019-10-24 19:45:42 +, Ali ‡ehreli said:

One practical reason is, the number of their instances cannot be known 
when the interface (or base class) is compiled.

...


Ali, first, thanks a lot for your answers.

If the compiler is a 1-pass one I see the problem, otherwise one could 
first get a "total overview" and create the necessary vtbl entries 
after everything is known. Maybe this is not "how a compiler is 
implemented" but the problem sounds solvable for me.


However, your solution works too. Thanks again.

--
Robert M. Münch
http://www.saphirion.com
smarter | better | faster



Re: ... use of ... is hidden by ...; use alias ... to introduce base class overload set ??

2019-10-24 Thread Ali Çehreli via Digitalmars-d-learn

On 10/24/2019 10:57 AM, Robert M. Münch wrote:

> Unfortunately, member function template instances are never virtual
> functions, so you can't override them."
>
> Is there a reason why these type of functions are not virtual or can't
> be made virtual?

One practical reason is, the number of their instances cannot be known 
when the interface (or base class) is compiled.


interface I {
  void foo();
  void bar();
}

When the compiler compiles that interface, it generates a vtbl (virtual 
function pointer table) with 2 entries in it. (As usual, those entries 
are indexed by 0 and 1.)


class C : I {
  // ...
}

When compiling the above class, the compiler generates a vtbl for C, and 
populates the entries with addresses of C.foo and C.bar.


  obj.bar();

When compiling the above code, compiler uses the equivalent of the 
following:


  obj.vtbl[1]();

In the case of member function templates, because the number of their 
instances are not known, the compiler cannot know how many entries to 
have in such an interface's vtbl. (Note that the compilation of I and C 
would ordinarily be separate from the calling code.)


  obj.someTemplate(42);

Which vtbl entry corresponds to the 'int' instance?

  obj.vtbl[???]();

This cannot be known as different compilation units instantiate 
templates according to their own uses. There is no common place to 
determine the length and entries of vtbls of I and C.


Ali




Re: ... use of ... is hidden by ...; use alias ... to introduce base class overload set ??

2019-10-24 Thread Robert M. Münch via Digitalmars-d-learn

On 2019-10-23 17:22:38 +, Ali ‡ehreli said:


On 10/23/2019 02:43 AM, Robert M. Münch wrote:

 >> Unfortunately, member function template instances are never virtual
 >> functions, so you can't override them.
 >
 > What I don't understand is:
 >
 > 1. The RX lib has a member function template and than an instance of it
 > using type Oberver!E.
 >
 > 2. I'm creating a new type and want to use the same pattern but now with
 > my type. But it seems that D reduces my own type which leads to the
 > ambigty of which function now to use. Whereas I would expect that D uses
 > the most specific type first.

That is exactly the case (for D, C++, etc.). However, the function must 
be virtual. Imagine an object is being accessed by it base interface, 
only the virtual function calls will be dispatched to the most specific 
type. Non-virtual functions will be called on the base type.


Yes, I know and the problem seems to be what you mentioned before: "But 
I think you have a member function template in the base class. 
Unfortunately, member function template instances are never virtual 
functions, so you can't override them."


Is there a reason why these type of functions are not virtual or can't 
be made virtual?


For that reason, even though I've managed to remove your compilation 
error below, you will not like how it behaves.


 > The pastbin is the minimal code example. And yes, I'm sure there is a
 > (simple) way out...

Replacing FilterSubject with the following removes the compilation error:

static class FilterSubject : SubjectObject!message {

   SI spitialIndex;

   this(){
 spitialIndex = new SI();
   }

   auto subscribe(T)(T t)
   if (!is (T == myWidget))
   {
 return typeof(super).subscribe(t);
   }

   Disposable subscribe(T)(T observer)
   if (is (T == myWidget))
   {
 spitialIndex.insert(observer.x, observer.y, 
cast(long)cast(void*)observer);


 return NopDisposable.instance;
   }
}


Ah, that's pretty neat. I think that is what I need. I have to get used 
to this template variant handling feature.



However...

   auto rx_message = new FilterSubject;

The type of rx_message is FilterSubject above. When one calls 
.subscribe() on it, only FilterSubject.subscribe templates will be 
involved. Perhaps that's exactly what you want.


Yes.


However... :)

Accessing rx_message through a base class interface will call a 
different set of .subscribe() functions (the ones on the base even for 
myWidget!):


   SubjectObject!message rx_message = new FilterSubject;

Now rx_message is the base type and only now you get "Hit!" printed.


Yes, that fits. Because only when thîs specific type is used the 
specialized implementation should be used.


Again, maybe this is exactly what you want but beware that different 
sets of functions will be called depending on what interface of the 
object you are using.


Yes, I understand and this is a very elegant way to keep the same 
interface but with different behaviour depending on the type. Very 
useful.


--
Robert M. Münch
http://www.saphirion.com
smarter | better | faster



Re: ... use of ... is hidden by ...; use alias ... to introduce base class overload set ??

2019-10-23 Thread Ali Çehreli via Digitalmars-d-learn

On 10/23/2019 02:43 AM, Robert M. Münch wrote:

>> Unfortunately, member function template instances are never virtual
>> functions, so you can't override them.
>
> What I don't understand is:
>
> 1. The RX lib has a member function template and than an instance of it
> using type Oberver!E.
>
> 2. I'm creating a new type and want to use the same pattern but now with
> my type. But it seems that D reduces my own type which leads to the
> ambigty of which function now to use. Whereas I would expect that D uses
> the most specific type first.

That is exactly the case (for D, C++, etc.). However, the function must 
be virtual. Imagine an object is being accessed by it base interface, 
only the virtual function calls will be dispatched to the most specific 
type. Non-virtual functions will be called on the base type.


For that reason, even though I've managed to remove your compilation 
error below, you will not like how it behaves.


> The pastbin is the minimal code example. And yes, I'm sure there is a
> (simple) way out...

Replacing FilterSubject with the following removes the compilation error:

static class FilterSubject : SubjectObject!message {

  SI spitialIndex;

  this(){
spitialIndex = new SI();
  }

  auto subscribe(T)(T t)
  if (!is (T == myWidget))
  {
return typeof(super).subscribe(t);
  }

  Disposable subscribe(T)(T observer)
  if (is (T == myWidget))
  {
spitialIndex.insert(observer.x, observer.y, 
cast(long)cast(void*)observer);


return NopDisposable.instance;
  }
}

However...

  auto rx_message = new FilterSubject;

The type of rx_message is FilterSubject above. When one calls 
.subscribe() on it, only FilterSubject.subscribe templates will be 
involved. Perhaps that's exactly what you want.


However... :)

Accessing rx_message through a base class interface will call a 
different set of .subscribe() functions (the ones on the base even for 
myWidget!):


  SubjectObject!message rx_message = new FilterSubject;

Now rx_message is the base type and only now you get "Hit!" printed.

Again, maybe this is exactly what you want but beware that different 
sets of functions will be called depending on what interface of the 
object you are using.


Ali




Re: ... use of ... is hidden by ...; use alias ... to introduce base class overload set ??

2019-10-23 Thread Robert M. Münch via Digitalmars-d-learn

On 2019-10-22 20:59:41 +, Ali ‡ehreli said:


That says "private paste" for me.


Ups, sorry and thanks for letting me know.



But I think you have a member function template in the base class.


This the lib I use: 
https://github.com/lempiji/rx/blob/dev/source/rx/subject.d and which 
gives the error.


On lines 72ff it has:

   Disposable subscribe(T)(T observer)
   {
   return subscribe(observerObject!E(observer));
   }

   Disposable subscribe(Observer!E observer)
   {


Which looks exactly like what you mention, if I understand it correctly.

Unfortunately, member function template instances are never virtual 
functions, so you can't override them.


What I don't understand is:

1. The RX lib has a member function template and than an instance of it 
using type Oberver!E.


2. I'm creating a new type and want to use the same pattern but now 
with my type. But it seems that D reduces my own type which leads to 
the ambigty of which function now to use. Whereas I would expect that D 
uses the most specific type first.


I'm pretty sure there is a way out. Can you try showing minimal code 
again please.


The pastbin is the minimal code example. And yes, I'm sure there is a 
(simple) way out... for some advanced guys like you. Still learning a 
lot here...


--
Robert M. Münch
http://www.saphirion.com
smarter | better | faster



Re: ... use of ... is hidden by ...; use alias ... to introduce base class overload set ??

2019-10-22 Thread Ali Çehreli via Digitalmars-d-learn

On 10/22/2019 01:23 PM, Robert M. Münch wrote:

> The whole code
> can be found here: https://pastebin.com/5BTT16Ze

That says "private paste" for me. But I think you have a member function 
template in the base class. Unfortunately, member function template 
instances are never virtual functions, so you can't override them.


I'm pretty sure there is a way out. Can you try showing minimal code 
again please.


Thanks,
Ali




Re: ... use of ... is hidden by ...; use alias ... to introduce base class overload set ??

2019-10-22 Thread Robert M. Münch via Digitalmars-d-learn

On 2019-10-21 18:02:06 +, Robert M. Münch said:


This now gives:

rx_filter_subject.d(66,23): Error: 
rx_filter_subject.FilterSubject.subscribe called with argument types 
(myWidget) matches both:


/Users/robby/.dub/packages/rx-0.13.0/rx/source/rx/subject.d(72,16):
rx.subject.SubjectObject!(message).SubjectObject.subscribe!(myWidget).subscribe(myWidget 
observer)


and:

rx_filter_subject.d(47,14): 
rx_filter_subject.FilterSubject.subscribe(myWidget observer)


So, now there is an ambiguty.


I'm really stuck on this which looks like a dead-lock to me. Adding 
"override" gives:


class myWidget : Observer!message {...}

class FilterSubject : SubjectObject!message {
 override Disposable subscribe(myWidget observer){...}
}

rx_filter_subject.d(47,23): Error: function Disposable 
rx_filter_subject.FilterSubject.subscribe(myWidget observer) does not 
override any function, did you mean to override template 
rx.subject.SubjectObject!(message).SubjectObject.subscribe(T)(T 
observer)?


rx_filter_subject.d(47,23):Functions are the only declarations 
that may be overriden


So, I can't override but when I use an alias I get an ambiguty error... 
now what?


The only solution I have is to use a different name, but that would 
change the interface and run against all the OOP ideas. The whole code 
can be found here: https://pastebin.com/5BTT16Ze



--
Robert M. Münch
http://www.saphirion.com
smarter | better | faster



Re: ... use of ... is hidden by ...; use alias ... to introduce base class overload set ??

2019-10-21 Thread Robert M. Münch via Digitalmars-d-learn

On 2019-10-21 07:04:33 +, John Chapman said:


This should work:

class FilterSubject : SubjectObject!message {
   alias subscribe = typeof(super).subscribe;
   Disposable subscribe(myWidget observer){...}
}


This now gives:

rx_filter_subject.d(66,23): Error: 
rx_filter_subject.FilterSubject.subscribe called with argument types 
(myWidget) matches both:


/Users/robby/.dub/packages/rx-0.13.0/rx/source/rx/subject.d(72,16):
rx.subject.SubjectObject!(message).SubjectObject.subscribe!(myWidget).subscribe(myWidget 
observer)


and:

rx_filter_subject.d(47,14): 
rx_filter_subject.FilterSubject.subscribe(myWidget observer)


So, now there is an ambiguty.

--
Robert M. Münch
http://www.saphirion.com
smarter | better | faster



Re: ... use of ... is hidden by ...; use alias ... to introduce base class overload set ??

2019-10-21 Thread John Chapman via Digitalmars-d-learn

On Sunday, 20 October 2019 at 21:45:35 UTC, Robert M. Münch wrote:

class myWidget : Observer!message {...}

class FilterSubject : SubjectObject!message {
 Disposable subscribe(myWidget observer){...}
}


I tried to add "alias subscribe = SubjectObject.subscribe;" in 
different places, but that didn't help. Nor do I have any how 
that should help...


This should work:

class FilterSubject : SubjectObject!message {
  alias subscribe = typeof(super).subscribe;
  Disposable subscribe(myWidget observer){...}
}


... use of ... is hidden by ...; use alias ... to introduce base class overload set ??

2019-10-20 Thread Robert M. Münch via Digitalmars-d-learn

I get this error message, which doesn't tell me a lot:

rx_filter_subject.d(38,8): Error: class rx_filter_subject.FilterSubject 
use of 
rx.subject.SubjectObject!(message).SubjectObject.subscribe(Observer!(message) 
observer) is hidden by FilterSubject; use alias subscribe = 
SubjectObject.subscribe; to introduce base class overload set


I have in file rx_filter_subject:

class myWidget : Observer!message {...}

class FilterSubject : SubjectObject!message {
 Disposable subscribe(myWidget observer){...}
}


I tried to add "alias subscribe = SubjectObject.subscribe;" in 
different places, but that didn't help. Nor do I have any how that 
should help...


I understand that my subscribe(myWidget observer) function seems to 
hide the base class subscribe function. But I don't care about the base 
class one. So, I want to hide it when a FilterSubject is used.


--
Robert M. Münch
http://www.saphirion.com
smarter | better | faster