Thread overview | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
September 22, 2004 MIID Mixins auto aliasing | ||||
---|---|---|---|---|
| ||||
I really love mixins, but there are one annoying thing in D - dirty work for aliasing (for overload) _each_ function mixed in. For example, in my vector library, I have one template consists of many functions. That template mixed in module scope for each vector type. At now I must write alias for each functions, and when count of these functions grow, it becomes a pain. And what if I have 100 functions? I do not want to type each function :(. template TMixin(T) { void foo1() {} void foo2() {} ... void foo100() {} } mixin TMixin(T1) Mixin1; alias Mixin1.foo1 foo1; alias Mixin1.foo1 foo2; ... alias Mixin1.foo100 foo100; mixin TMixin(T2) Mixin2; alias Mixin2.foo1 foo1; alias Mixin2.foo1 foo2; ... alias Mixin2.foo100 foo100; I need for: mixin TMixin(T1) alias; or mixin TMixin(T1) Mixin1; alias Mixin1.* *; or something simular by functionality. |
September 22, 2004 Re: MIID Mixins auto aliasing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ilya Zaitseff | um... perhaps I misunderstand how mixins are used, but you're using them like template instances which is not even valid.
As I understood it (and thus implemented it in D.NET) mixins ARE the auto aliasing for template instances. To use your example:
> template TMixin(T)
> {
> void foo1() {}
> void foo2() {}
> ...
> void foo100() {}
> }
>
> mixin TMixin(T1);
actually generates:
> void foo1() {}
> void foo2() {}
> ...
> void foo100() {}
in the scope in which it is declared.
Of course, rereading over your post I'm not sure what the impact is on function overloads, so I may be addressing the wrong issue.
-Deja
Ilya Zaitseff wrote:
> I really love mixins, but there are one annoying thing in D - dirty work for aliasing (for overload)
> _each_ function mixed in.
> For example, in my vector library, I have one template consists of many functions. That template mixed in
> module scope for each vector type. At now I must write alias for each functions, and when count of these
> functions grow, it becomes a pain.
>
> And what if I have 100 functions? I do not want to type each function :(.
>
> template TMixin(T)
> {
> void foo1() {}
> void foo2() {}
> ...
> void foo100() {}
> }
>
> mixin TMixin(T1) Mixin1;
> alias Mixin1.foo1 foo1;
> alias Mixin1.foo1 foo2;
> ...
> alias Mixin1.foo100 foo100;
>
> mixin TMixin(T2) Mixin2;
> alias Mixin2.foo1 foo1;
> alias Mixin2.foo1 foo2;
> ...
> alias Mixin2.foo100 foo100;
>
> I need for:
>
> mixin TMixin(T1) alias;
>
> or
>
> mixin TMixin(T1) Mixin1;
> alias Mixin1.* *;
>
> or something simular by functionality.
|
September 22, 2004 Re: MIID Mixins auto aliasing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Deja Augustine | In article <cir7db$1i1n$1@digitaldaemon.com>, Deja Augustine says... > >um... perhaps I misunderstand how mixins are used, but you're using them like template instances which is not even valid. > >As I understood it (and thus implemented it in D.NET) mixins ARE the auto aliasing for template instances. To use your example: > > > template TMixin(T) > > { > > void foo1() {} > > void foo2() {} > > ... > > void foo100() {} > > } > > > > mixin TMixin(T1); > >actually generates: > > > void foo1() {} > > void foo2() {} > > ... > > void foo100() {} > >in the scope in which it is declared. > >Of course, rereading over your post I'm not sure what the impact is on function overloads, so I may be addressing the wrong issue. Mixins work like imports. That is, they aren't automatically considered for overload resolution. Here's an example: # template T() { # void func(char); # } # # class C { # public: # mixin T!(); # void func(int); # } # # C c = new C(); # c.func('a'); In the above, C.func(int) will be called. In order to have the mixin function available for overload resolution it has to be aliased in that scope. This is conceptually similar to subclassing: # class A { # public: # void func(char); # } # # class B : A { # public: # void func(int); # } # # B b = new B(); # b.func('a'); In the above example, func(int) will be called as well. Note that in both cases, func(char) would be visible if func(int) were not declared. Sean |
September 22, 2004 overload bug - Re: MIID Mixins auto aliasing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | On Wed, 22 Sep 2004 15:06:01 +0000, Sean Kelly wrote:
>>Of course, rereading over your post I'm not sure what the impact is on function overloads, so I may be addressing the wrong issue.
>
> This is
> conceptually similar to subclassing:
>
> # class A {
> # public:
> # void func(char);
> # }
> #
> # class B : A {
> # public:
> # void func(int);
> # }
> #
> # B b = new B();
> # b.func('a');
>
> In the above example, func(int) will be called as well.
>
> Note that in both cases, func(char) would be visible if func(int) were not
> declared.
>
this wrong!
from the docs:
"
Integer Promotions
The following types are implicitly converted to int:
bit
byte
ubyte
short
ushort
enum
char
wchar
dchar
"
if we replace b.func(int) by b.func(float) it's still called!
it's a bug.
I'm posting it on the bugs group.
(If it's a feature it should be revised.)
Ant
|
September 22, 2004 Re: overload bug - Re: MIID Mixins auto aliasing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ant | In article <pan.2004.09.22.15.56.33.270961@yahoo.ca>, Ant says... > >if we replace b.func(int) by b.func(float) it's still called! >it's a bug. It's not a bug, it's how function visibility and overload resolution is handled in D (and in C++). Sean |
September 22, 2004 Re: overload bug - Re: MIID Mixins auto aliasing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | Sean Kelly wrote:
> In article <pan.2004.09.22.15.56.33.270961@yahoo.ca>, Ant says...
>
>>if we replace b.func(int) by b.func(float) it's still called!
>>it's a bug.
>
>
> It's not a bug, it's how function visibility and overload resolution is handled
> in D (and in C++).
>
>
> Sean
>
>
Agreed, You are overriding a function *name* of another class, this means that when overriding you should only be able to call the function b.func(float) because it is the only visible one.
If you want to be able to call b.func(char) or b.func(int) as well you need to specify this explicitly with the override attribute in the subclass.
Regards,
Sjoerd
|
September 22, 2004 Re: overload bug - Re: MIID Mixins auto aliasing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sjoerd van Leent | Sjoerd van Leent wrote:
> Sean Kelly wrote:
>
>> In article <pan.2004.09.22.15.56.33.270961@yahoo.ca>, Ant says...
>>
>>> if we replace b.func(int) by b.func(float) it's still called!
>>> it's a bug.
>>
>>
>>
>> It's not a bug, it's how function visibility and overload resolution is handled
>> in D (and in C++).
>>
>>
>> Sean
>>
>>
> Agreed, You are overriding a function *name* of another class, this means that when overriding you should only be able to call the function b.func(float) because it is the only visible one.
>
> If you want to be able to call b.func(char) or b.func(int) as well you need to specify this explicitly with the override attribute in the subclass.
>
> Regards,
> Sjoerd
The override attribute does nothing to change the functionality (unless that's recently changed). A function marked "override" doesn't behave any differently from one without it. It's there purely as a debugging tool. To quote the documentation:
"...It means that the function must override a function with the same name and parameters in a base class. The override attribute is useful for catching errors when a base class's member function gets its parameters changed, and all derived classes need to have their overriding functions updated."
All it does is generate a compiler error if a subclass, of the class with the "override" method, does not implement a version of that method.
It's something akin to a pure virtual function except that it can have an implementation in the base class.
-Deja
|
September 22, 2004 Re: overload bug - Re: MIID Mixins auto aliasing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Deja Augustine | Deja Augustine wrote:
> Sjoerd van Leent wrote:
>
>> Sean Kelly wrote:
>>
>>> In article <pan.2004.09.22.15.56.33.270961@yahoo.ca>, Ant says...
>>>
>>>> if we replace b.func(int) by b.func(float) it's still called!
>>>> it's a bug.
>>>
>>>
>>>
>>>
>>> It's not a bug, it's how function visibility and overload resolution is handled
>>> in D (and in C++).
>>>
>>>
>>> Sean
>>>
>>>
>> Agreed, You are overriding a function *name* of another class, this means that when overriding you should only be able to call the function b.func(float) because it is the only visible one.
>>
>> If you want to be able to call b.func(char) or b.func(int) as well you need to specify this explicitly with the override attribute in the subclass.
>>
>> Regards,
>> Sjoerd
>
>
> The override attribute does nothing to change the functionality (unless that's recently changed). A function marked "override" doesn't behave any differently from one without it. It's there purely as a debugging tool. To quote the documentation:
>
> "...It means that the function must override a function with the same name and parameters in a base class. The override attribute is useful for catching errors when a base class's member function gets its parameters changed, and all derived classes need to have their overriding functions updated."
>
> All it does is generate a compiler error if a subclass, of the class with the "override" method, does not implement a version of that method.
>
> It's something akin to a pure virtual function except that it can have an implementation in the base class.
>
> -Deja
Maybe my explanation lacked a little. With override I did mean what you said:
"...It means that the function must override a function with the same name and parameters in a base class..."
It enforces you to use the same parameters, so you need to specify b.func(int). As I am rereading the case, it seems that a mixin would be better, because you only need one rule, not a complete reimplementation.
Regards,
Sjoerd
|
September 22, 2004 Re: overload bug - Re: MIID Mixins auto aliasing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | On Wed, 22 Sep 2004 18:40:14 +0000, Sean Kelly wrote:
> In article <pan.2004.09.22.15.56.33.270961@yahoo.ca>, Ant says...
>>
>>if we replace b.func(int) by b.func(float) it's still called!
>>it's a bug.
>
> It's not a bug, it's how function visibility and overload resolution is handled
> in D (and in C++).
>
>
> Sean
this is nonsence, I expect the right function to be called, not the one that is "closer"...
let's call it nonsence and convince Walter to change it. who can write a justification and present it on a PDF?
Why do we have char converted to int in the first place? what is the justification (besides historical reasons?)
this is what you should expect from a strong type language:
##################
public class Over
{
static class A
{
void func(char a)
{
System.out.println("A.func");
}
}
static class B extends A
{
void func(int i)
{
System.out.println("B.func");
}
}
public static void main(String[] args)
{
B b = new B();
b.func('a');
}
}
###################
$ javac Over.java
$ java Over
A.func
###################
(I don't care how C++ does it (some might care))
Ant
|
September 22, 2004 Re: overload bug - Re: MIID Mixins auto aliasing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sjoerd van Leent | On Wed, 22 Sep 2004 20:59:56 +0200, Sjoerd van Leent wrote:
> Sean Kelly wrote:
>> In article <pan.2004.09.22.15.56.33.270961@yahoo.ca>, Ant says...
>>
>>>if we replace b.func(int) by b.func(float) it's still called!
>>>it's a bug.
>>
>>
>> It's not a bug, it's how function visibility and overload resolution is handled
>> in D (and in C++).
>>
>>
>> Sean
>>
>>
> Agreed, You are overriding a function *name* of another class, this means that when overriding you should only be able to call the function b.func(float) because it is the only visible one.
>
> If you want to be able to call b.func(char) or b.func(int) as well you need to specify this explicitly with the override attribute in the subclass.
>
> Regards,
> Sjoerd
Disagreed, the signature of the function should be consired first, the the automatic conversion.
you are not overrinding you are overloading.
it's not the only visible, they have different signatures.
if you want to call an int function with a char to
func(cast(int) c);
Ant
|
Copyright © 1999-2021 by the D Language Foundation