I broke generics.

Monkey Forums/Monkey Programming/I broke generics.

Belimoth(Posted 2012) [#1]
Interface IA
	Method DoA:Void()
End

Class EntityBase Implements IA
	Field a:IA
	
	Method DoA:Void()
		a.DoA()
	End
End

Class Entity<IA> Extends EntityBase
	Field a := New IA()
End

Class A0 Implements IA
	Method DoA:Void()
		Print "A0"
	End
End

Class A1 Implements IA
	Method DoA:Void()
		Print "A1"
	End
End

Function Main()
	Local entity := New Entity<A0>
	entity.DoA()
End


"Memory Access Violation," even in debug mode.

Exciting stuff.


Belimoth(Posted 2012) [#2]
Okay so I experimented some more, importing the reflection module caused an actually useful error.
Field 'a' in Entity<A0> overrides existing declaration in class EntityBase.

I guess the second 'a' Field was never even included in the build, and the memory access violation was for calling a method of a Null object.


Belimoth(Posted 2012) [#3]
I achieved the architecture and functionality I wanted with something like this.




muddy_shoes(Posted 2012) [#4]
Looking at the code, monkey is just silently dropping the initialisation of 'a' in the subclass when there's an override. I'd say that's a bug.

Has narrowing of generics by type been implemented in v67? If not that code probably isn't doing what you think. 'IA' is just being used as a type alias in the same way that 'T' is. You can put any object in as the generic initialiser (although it'll fail on the assignment in your last structure).


Belimoth(Posted 2012) [#5]
I wasn't aware what the term ("narrowing") was for that until now.



I had been doing that because I thought that was how to make sure that the <class> had a DoStuff() method but you're right it doesn't work like I thought.


muddy_shoes(Posted 2012) [#6]
I wasn't aware what the term ("narrowing") was for that until now.


I just picked a word that seemed descriptive. I don't know if there is an "official" term for it. Java calls them bounded types.


Belimoth(Posted 2012) [#7]
I do a lot of tests to see what kind of architectures can be managed with odd arrangements of generics and interfaces and reflection. Bounded types sounds like a nifty feature. One of my experiments was to see if you could have something like

Field member:{IA, IB}


Where any object can be put in the member field as long as it is an instance of a class that implements both Interface IA and Interface IB. Could bounded types allow this kind of thing? Or are they only ever used in generics.

It seems like it could be done pretty easily but I have absolutely no knowledge about how type-checking is done under the hood.

An easy workaround would be to make
Interface InterfaceAB Extends InterfaceA, InterfaceB
End


But then you'd have to make a new interface for every combination of Interfaces.

To make a class valid for these kinds of assignments they'd have to look like this:
Class MyClass Implements A, B, C, AB, AC, BC, ABC

An instance of this class could go in any slot that requires some or all of the possible interfaces. But it seems like there should be a better way.

Compound interfaces could be generated the same way generics are built, and then added to any class that implements those two interfaces.

I dunno, I'm just brainstorming.