About Monkey 2 › Forums › Monkey 2 Programming Help › "Class Thing[T] Extends T" won't compile
This topic contains 11 replies, has 3 voices, and was last updated by
arpie
2 years, 4 months ago.
-
AuthorPosts
-
November 29, 2016 at 8:24 pm #5492
I can’t get pointy brackets to appear in the title. It should be :
Class Thing<T> Extends T
When I try to build, I get the error :
Error : Type ‘T?’ is not a valid super class type
This worked in Monkey1. Will it one day work in Monkey2?
November 30, 2016 at 2:07 am #5494I dont know is it bug or not, but I am interested in example of such using.
Can you post code from monkey1?
For me it looks like incorrect – you cant overload methods and using other members of template T.
Maybe you forget to add ‘Where T…’ keyword to refine T?
November 30, 2016 at 10:10 pm #5509I’ll try to put together a trivial example. While you’re waiting, could I ask you to explain what you mean in your last sentence? As far as I can see, ‘Where’ isn’t a keyword in Monkey1 or 2. What do you mean by refine T?
November 30, 2016 at 11:18 pm #5511Here is a Monkey1 implementation of the ‘composte‘ pattern (commonly used for GUI widgets, amongst other things). The classes here have a bare minimum of functionality – the Container class needs Remove(), Sort(), etc… and the Widget() probably wants some coordinates, size, etc. but that’s not the point. What I am trying to demonstrate is that the Container Class is basically a mixin and can turn any class into a container for itself (it turns a component into a composite). I could have missed out the Interface but I think it adds to the usefulness of the concept by not forcing components to inherit from the Widget class.
I haven’t yet used this in any real apps so I may have missed some fundamental issue that renders it useless… let me know if you spot something!
Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869StrictInterface IWidgetMethod Render:Void()End InterfaceClass Widget Implements IWidgetField _id:StringMethod Render:Void() AbstractEnd ClassClass Container<T, I> Extends TField _items := New Stack<I>()Method Add:Void(item:I)_items.Push(item)End MethodMethod ObjectEnumerator:stack.Enumerator<I>()Return _items.ObjectEnumerator()End MethodEnd ClassClass Frame Extends Container<Widget, IWidget> Implements IWidgetMethod New(id:String)_id = idEnd MethodMethod Render:Void()Print("Frame " + _id + " contains :")For Local w:IWidget = Eachin Selfw.Render()NextEnd MethodEnd ClassClass Button Extends WidgetMethod New(id:String)_id = idEnd MethodMethod Render:Void()Print("A Button with id " + _id)End MethodEnd ClassFunction Main:Int()Local frame := New Frame("F1")Local frame2 := New Frame("F2")'Put some button widgets into a frame widgetframe.Add(New Button("B1"))frame.Add(New Button("B2"))frame.Add(New Button("B3"))frame.Add(New Button("B4"))'Render the frameframe.Render()'Now, since the Frame class indirectly extends the Widget class (through the'use of the Container generic), we can also treat the frame as a widget and'place it inside a second frame.frame2.Add(frame)'And render it allframe2.Render()Return TrueEndNovember 30, 2016 at 11:57 pm #5512Where is a keyword of monkey2 and it has highlighting in Ted2.
Used like this:
Monkey1Interface IGenericInterface Where T Implements INumericIn your example code you don’t use T inside of Container, so why to use it at all?
What do you mean by refine T?
something like this:
Monkey1Class Container<I> Where I Implements IWidgetif you use where you prevent incorrect type of elements that can be added to container – now only elements with interface IWidget would work, for other you get compiler error. Profit!
December 1, 2016 at 8:34 am #5528Where is Where documented?
I don’t use T directly inside Container, no, but used as I have, it allows me to turn any class into a Container without having to rewrite the Container methods. It allows me to use Container as a mixin with any other class. The key point is that in my example Frame extends both Container and Widget – it inherits all methods from both classes. I guess you could call it multiple inheritance but that has a bad reputation so it’s a term I prefer to avoid.
December 1, 2016 at 9:38 am #5529There is no docs for this yet (I never seen). I hope it will be added later.
You can find a few topics on this forum by request ‘Where T’.
“Where” in mx2 works like in c#, google “c# where” for more info.
I don’t use T directly inside Container, no, but used as I have, it allows me to turn any class into a Container without having to rewrite the Container methods. It allows me to use Container as a mixin with any other class. The key point is that in my example Frame extends both Container and Widget – it inherits all methods from both classes. I guess you could call it multiple inheritance but that has a bad reputation so it’s a term I prefer to avoid.
It looks like that solution for you is using
Monkey1Class Container<I> Where I Implements IWidgetSo you can add any widget into container (they all implement IWidget), and you also can add frames into container (it implements IWidget too).
December 1, 2016 at 5:47 pm #5536It looks like that solution for you is using
Class Container<I> Where I Implements IWidget
So you can add any widget into container (they all implement IWidget), and you also can add frames into container (it implements IWidget too).
That’s not really the same thing. In a way it’s the opposite of what I am trying to achieve. I want the Container class to be as generic and reusable as possible. What I am trying to avoid is having to re-implement the Container interface in the Frame class. I want to inherit the implementations (not just the interfaces) of Widget and Container into one Frame class. I don’t want a Container into which I can put Frames and Widgets. I want a Frame that IS a container (into which I can put Frames, Widgets, etc…)
Of course, I could achieve what I want by avoiding the Container class completely – just implement the IContainer interface in the Frame class but…
I also want to be able to reuse the Container class/mixin elsewhere, for example, for a Phrase composite that can contain Word components (or other Phrases). Or a Task class that can be extended into a Project container, allowing a heirarchy of Projects, Subprojects and Tasks….. all using the same Container Mixin to implement a generic heirarchy of objects.
Your suggestions help to enforce the relationship between the interfaces but they don’t avoid the problem of having to rewrite the implementations of those interfaces in many places. I hate having to rewrite the same code twice!
The ideal solution to all this would be for Mark to implement Mixins (or Traits, or whatever you want to call them).
December 2, 2016 at 4:02 am #5539I have more attentively looked at your code.
You want to extend Container with template type. So my previous answer is wrong.
The ideal solution to all this would be for Mark to implement Mixins (or Traits, or whatever you want to call them).
It looks like the only way.:)
December 4, 2016 at 6:32 am #5576Looks like Mark has seen your Post..
https://github.com/blitz-research/monkey2/commit/f76ff5d1097cbce36b4fcc704c68436b789aeb77
December 4, 2016 at 8:37 pm #5589Woohoo! Mark, you are a superstar.
December 6, 2016 at 10:15 pm #5628Sorry, @Mark, I’m removing the super from my last comment, thus demoting you to ‘star’ until you get round to making this work when the Classes in question are in different source files (see below). Tested with a namespace declaration, too, with the same results. On the other hand, if you were to implement a dedicated Mixin/Traits syntax then I would have to promote you to ‘demigod’!
File test.monkey2 :
Monkey12345678910#Import "testmixin"Class ThingEnd ClassClass ThingList Extends TestMixin<Thing>End ClassFunction Main()End FunctionFile testmixin.monkey2 :
Monkey1234567Class TestMixin<T> Extends TPublicMethod New()End MethodEnd ClassCompilation error :
Mx2cc version 1.1.02
***** Building app ‘/home/arpie/Projects/BiaB/MazeM2/test.monkey2’ *****
Parsing…
Semanting…
Translating…
Compiling…
Build error: System command ‘g++ -I”/home/arpie/Coding/Monkey/Monkey2/modules/” -I”/home/arpie/Coding/Monkey/Monkey2/modules/monkey/native” -I”/home/arpie/Projects/BiaB/MazeM2/” -std=c++11 -c -o “/home/arpie/Projects/BiaB/MazeM2/test.buildv1.1.02/linux_debug/build/_1src_2test_0testmixin.cpp.o” “/home/arpie/Projects/BiaB/MazeM2/test.buildv1.1.02/linux_debug/src/test_testmixin.cpp”‘ failed.g++ -I”/home/arpie/Coding/Monkey/Monkey2/modules/” -I”/home/arpie/Coding/Monkey/Monkey2/modules/monkey/native” -I”/home/arpie/Projects/BiaB/MazeM2/” -std=c++11 -c -o “/home/arpie/Projects/BiaB/MazeM2/test.buildv1.1.02/linux_debug/build/_1src_2test_0testmixin.cpp.o” “/home/arpie/Projects/BiaB/MazeM2/test.buildv1.1.02/linux_debug/src/test_testmixin.cpp”
In file included from /home/arpie/Projects/BiaB/MazeM2/test.buildv1.1.02/linux_debug/src/../include/test_testmixin.h:12:0,
from /home/arpie/Projects/BiaB/MazeM2/test.buildv1.1.02/linux_debug/src/test_testmixin.cpp:2:
/home/arpie/Projects/BiaB/MazeM2/test.buildv1.1.02/linux_debug/src/../include/test_test.h:40:37: error: invalid use of incomplete type ‘struct t_default_TestMixin_1Tt_default_Thing_2’
struct t_default_ThingList : public t_default_TestMixin_1Tt_default_Thing_2{
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/arpie/Projects/BiaB/MazeM2/test.buildv1.1.02/linux_debug/src/test_testmixin.cpp:2:0:
/home/arpie/Projects/BiaB/MazeM2/test.buildv1.1.02/linux_debug/src/../include/test_testmixin.h:7:8: note: forward declaration of ‘struct t_default_TestMixin_1Tt_default_Thing_2’
struct t_default_TestMixin_1Tt_default_Thing_2;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
***** Fatal mx2cc error *****Internal mx2cc build error
-
AuthorPosts
You must be logged in to reply to this topic.