Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The set inheritance modification problem #37

Open
TheJJ opened this issue Apr 21, 2018 · 4 comments
Open

The set inheritance modification problem #37

TheJJ opened this issue Apr 21, 2018 · 4 comments
Labels
proposal pending discussion about something to do specification involves the nyan language specification

Comments

@TheJJ
Copy link
Member

TheJJ commented Apr 21, 2018

This kind of a design flaw, which we have to resolve.

The problem is that currently it is impossible that values in sets can be added and removed at the same time. This is required when a specialization (called Special) of a value is to be added to the set, but the parent of Special is already in the set.

This is a problem because often entities define a preset of values, which then need to be specialized, and the old ones invalidated.

Possible idea:
set insertion in such a way that some keyword (e.g. {@objectname, ...}) marks it as unique, and child objects of this will replace it. We would need 3 operators:

  • @insertion: Any child object of this insertion will delete it
  • +insertion: This will delete all of its parents in the set (even if those were not annotated with @)
  • !insertion: This will ignore that the insertion of a child should delete this entry (-> ignore the + annotation effect)

Example:

# each unit can move by default
Unit(Entity):
    Move(Ability):
        speed = 1.0
    abilities += {Move}

# but the villager now changes the speed!
Villager(Unit):
    VillagerMove(Unit.Move):
        speed = 10.0
    # Move has to be replaced, otherwise we have 2x Move!
    abilities += {VillagerMove}

Solution with annotations:

Unit(Entity):
    Move(Ability):
        speed = 1.0
    abilities += {@Move}

Villager(Unit):
    VillagerMove(Unit.Move):
        speed = 10.0
    # this now automatically replaces `Move` with `VillagerMove`
    abilities += {VillagerMove}

Possible solution without annotations:

Unit:
    ...

Movable:
    movespeed = ...

MovableUnit(Unit, Movable):
    ....

Villager(MovableUnit):
    movespeed = 10

But this solution makes use of the inheritance, and the member names would need redundant prefixes in order to remain unique. This can be improved a bit by the member name qualifications.

Quoting @mic-e:

also irgend ein keyword oder ne andere magic damit nyan hinzugefügte nyanobjekte die unterobjekte vom nyanobjekt sind dem des member gehört automatisch upgraded bei vererbten nyanobjekten wäre halt die ideale lösung denk ich

@TheJJ TheJJ added improvement improves existing functionality specification involves the nyan language specification proposal pending discussion about something to do labels Apr 21, 2018
@heinezen
Copy link
Member

I think the solution with annotations is the better one, since using inheritance could get convoluted for units with many different abilities. It's probably easier to explain, too. I would just suggest switching the symbols for the first and second operation as @ and + are already used in different contexts in nyan.

Using @ for the 2nd case instead of the 1st one would be better because this is more in line with @ signifying the override/replacement of an operator when its placed in front of it. In this context, it would signify the "override" of a parent with a child object which is very similar to the other use of @.

+ already appears in an entirely different context (patching inheritance), so I would avoid using it here. Maybe $, ~ or ? are better?

@MichaHoffmann
Copy link

MichaHoffmann commented May 8, 2018

Since this seems to be a syntactical problem, how about declaring the 3 possibilities like python decorators? i.e

Unit(Entity):
    @replacedByChild
    Move(Ability):
        speed = 1.0
    abilities += {Move}

Villager(Unit):
    VillagerMove(Unit.Move):
        speed = 10.0
    # this now automatically replaces `Move` with `VillagerMove`
    abilities += {VillagerMove}

@TheJJ TheJJ removed the improvement improves existing functionality label Sep 6, 2018
@TheJJ
Copy link
Member Author

TheJJ commented May 21, 2019

(Sorry for the very delayed reply.....) Unfortunately it's not just syntactic, we are changing the set semantics here and need to configure that syntactically. Using decorators (at least to annotate the object itself) is probably not such a good choice since in a different set, the rule may not apply. So this needs to be a configuration for each set.

@TheJJ
Copy link
Member Author

TheJJ commented Oct 3, 2020

@heinezen and I just found a solution for this.
The realization was that we need both directions for these modifications:

  • Inserting a specialized object into the set should replace all parents
  • Removing a parent object (may not be in the set itself) should remove all children
    This means the inheritance hierarchy should be enforced. This can be done by configuring the set to ensure the inheritance hierarchy by overwrites.
    Example:
Entity:
    abilities : set(Ability, hierarchy_overwrite=True) = {}

Unit(Entity):
    Move(Ability):
        speed = 1.0
    abilities += {Move}

Villager(Unit):
    VillagerMove(Unit.Move):
        speed = 10.0
    # VillagerMove replaces Move, since the set was configured with hierarchy_overwrite!
    abilities += {VillagerMove}

Regarding "Where is the border", i.e. when inserting a child, up until what level should parents be purged from the set? The "maximum anchestor" is the set's member type. In the above example, this means the VillagerMove insertion removes all parents in the inheritance line between Ability and VillagerMove, thus Move is replaced by VillagerMove.

This would be @mic-e's "ne andere magic" from his brainstorm in 2018 :) (or actually a "keyword" in the set creation!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal pending discussion about something to do specification involves the nyan language specification
Projects
None yet
Development

No branches or pull requests

3 participants