nim-lang / Nim

Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. Its design focuses on efficiency, expressiveness, and elegance (in that order of priority).
https://nim-lang.org
Other
16.55k stars 1.47k forks source link

Generic Inheritance-tree misbehavior #5687

Open dustinlacewell opened 7 years ago

dustinlacewell commented 7 years ago

Preface

Assuming you have the sdl2 and perlin packages installed:

The demo implements a 2D binary-space-partition graph. That is for a given 2D rectangle, split it either vertically or horizontally and get two new rectangles. Repeat.

The implementation of the binary tree is here: https://github.com/dustinlacewell/dadren/blob/46e66e41f7205b9f7f292d5fb27d68961517abeb/dadren/bsp.nim

It implements a simple inheritance tree:

BSPNode[T] -> Leaf[T]   # contains actual T content
BSPNode[T] -> ParentNode[T] -> VSplit[T] # has two BSPNode children
BSPNode[T] -> ParentNode[T] -> HSplit[T] # has two BSPNode children

Intended Implementation

The example that uses this BSP implementation is here: https://github.com/dustinlacewell/dadren/blob/46e66e41f7205b9f7f292d5fb27d68961517abeb/examples/bsp2/main.nim

In that example Color a simple ref object type is used as the T content for building the BSPTree. This all works as expected.

The BSPNode base type defines the parent field as BSPNode. This is not the ideal expression of the program's design. Only a ParentNode should ever be a parent in the graph. Therefore it would be ideal to have the BSPNode.parent field by of type ParentNode. This would avoid the otherwise unnecessary casts anytime the parent field is accessed:

https://github.com/dustinlacewell/dadren/blob/46e66e41f7205b9f7f292d5fb27d68961517abeb/dadren/bsp.nim#L134 https://github.com/dustinlacewell/dadren/blob/46e66e41f7205b9f7f292d5fb27d68961517abeb/dadren/bsp.nim#L160 https://github.com/dustinlacewell/dadren/blob/46e66e41f7205b9f7f292d5fb27d68961517abeb/dadren/bsp.nim#L172 https://github.com/dustinlacewell/dadren/blob/46e66e41f7205b9f7f292d5fb27d68961517abeb/dadren/bsp.nim#L177

Problem

When changing the BSPNode.parent field from type BSPNode to ParentNode the following error is generated:

bsp.nim(30, 20) Error: inheritance only works with non-final objects

With some exploration an unusual result was discovered. Make the following changes:

The compiler error is now:

bsp.nim(31, 17) Error: type mismatch: got (BSPNode[]) but expected 'float'

This would imply that, even though no type in the BSPNode hierarchy inherits from T, the compiler is some how conflating T into the resolution of BSPNode fields.

stale[bot] commented 4 years ago

This issue has been automatically marked as stale because it has not had recent activity. If you think it is still a valid issue, write a comment below; otherwise it will be closed. Thank you for your contributions.