Nim icon indicating copy to clipboard operation
Nim copied to clipboard

Ability to define different default values on inherited objects

Open dadadani opened this issue 3 years ago • 4 comments

Summary

One of the new functionalities of Nim 2.0 will be the possibility of defining default values for fields of objects. This is a very interesting concept, however it is not at the moment usable for inherited types.

Description

At the moment, identifying inherited objects is hard. We do have the of operator, but it’s not really useful: We can only check if an object is part of a specific sub-type, but not for example get the name if we don’t know it. If we can have different default values for a single field, it will be trivial to know what object we are interacting with, just by looking at the assigned “identifier”. This is especially useful if we need to create a generic procedure that needs to interact with multiple types.

Alternatives

No response

Standard Output Examples

type Macro* = ref object of RootObj
    id: int = 0

type MicroOne* = ref object of Macro
    id = 2

type MicroTwo* = ref object of Macro
    id = 301

proc identify(obj: Macro) =
    case obj.id
    of 2:
        echo "Object is MicroOne!"
    of 301:
        echo "Object is MicroTwo!"
    of 0:
        echo "Object is Macro!"
    else:
        echo "other/unknown object"

    if obj.id > 300:
        echo "id is higher than 300!"

identify(MicroOne())
identify(MicroTwo())
identify(Macro())

Backwards Compatibility

No response

Links

No response

dadadani avatar Nov 03 '22 17:11 dadadani

@ringabout are there any problems with this idea in principle? Seems to me to be just an implementation oversight.

Araq avatar Nov 04 '22 10:11 Araq

type Macro* = ref object of RootObj
    id: int

type MicroOne* = ref object of Macro
    id: int

gave Error: attempt to redefine: 'id' before. I think the solution is to remove this restriction, add a check for the type of id which should have the same type as its parent and if parents has a default field, its children should be allowed to redefine this field.

And handle these cases properly

type Macro* = ref object of RootObj
    id: int = 10

type MicroOne* = ref object of Macro

true

type Macro* = ref object of RootObj
    id: int = 10

type MicroOne* = ref object of Macro
    id: int

false

type Macro* = ref object of RootObj
    id: int

type MicroOne* = ref object of Macro
    id: int = 10

false

type Macro* = ref object of RootObj
    id: int = 10

type MicroOne* = ref object of Macro
    id: string = "123"

false

type Macro* = ref object of RootObj
    id: int = 0

type MicroOne* = ref object of Macro
    id: int

type MicroTwo* = ref object of Macro
    id = 301

false

ringabout avatar Nov 04 '22 10:11 ringabout

Field names and their conflicts have nothing to do with default values and inheritance!

Araq avatar Nov 04 '22 11:11 Araq

I have a related problem, which is:

type
  Geometry = object of RootObj
    name: string
  Sphere = object of Geometry
    # How to set default name for sphere?
    radius: float = 1.0
  Rectangle = object of Geometry
    # How to set default name for rectangle?
    size: array[2, float] = [1.0, 1.0]

Of course I don't want to redefine/duplicate an existing field.

anderflash avatar Aug 23 '23 09:08 anderflash